summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/apps/embeddedkonsole/MyPty.cpp7
1 files changed, 5 insertions, 2 deletions
diff --git a/core/apps/embeddedkonsole/MyPty.cpp b/core/apps/embeddedkonsole/MyPty.cpp
index 6421ab0..9adc248 100644
--- a/core/apps/embeddedkonsole/MyPty.cpp
+++ b/core/apps/embeddedkonsole/MyPty.cpp
@@ -19,96 +19,97 @@
19 problems that you can track down to this file, please have 19 problems that you can track down to this file, please have
20 a look into ../README.ports, too. 20 a look into ../README.ports, too.
21*/ 21*/
22 22
23/*! \file 23/*! \file
24*/ 24*/
25 25
26/*! \class TEPty 26/*! \class TEPty
27 27
28 \brief Ptys provide a pseudo terminal connection to a program. 28 \brief Ptys provide a pseudo terminal connection to a program.
29 29
30 Although closely related to pipes, these pseudo terminal connections have 30 Although closely related to pipes, these pseudo terminal connections have
31 some ability, that makes it nessesary to uses them. Most importent, they 31 some ability, that makes it nessesary to uses them. Most importent, they
32 know about changing screen sizes and UNIX job control. 32 know about changing screen sizes and UNIX job control.
33 33
34 Within the terminal emulation framework, this class represents the 34 Within the terminal emulation framework, this class represents the
35 host side of the terminal together with the connecting serial line. 35 host side of the terminal together with the connecting serial line.
36 36
37 One can create many instances of this class within a program. 37 One can create many instances of this class within a program.
38 As a side effect of using this class, a signal(2) handler is 38 As a side effect of using this class, a signal(2) handler is
39 installed on SIGCHLD. 39 installed on SIGCHLD.
40 40
41 \par FIXME 41 \par FIXME
42 42
43 [NOTE: much of the technical stuff below will be replaced by forkpty.] 43 [NOTE: much of the technical stuff below will be replaced by forkpty.]
44 44
45 publish the SIGCHLD signal if not related to an instance. 45 publish the SIGCHLD signal if not related to an instance.
46 46
47 clearify TEPty::done vs. TEPty::~TEPty semantics. 47 clearify TEPty::done vs. TEPty::~TEPty semantics.
48 check if pty is restartable via run after done. 48 check if pty is restartable via run after done.
49 49
50 \par Pseudo terminals 50 \par Pseudo terminals
51 51
52 Pseudo terminals are a unique feature of UNIX, and always come in form of 52 Pseudo terminals are a unique feature of UNIX, and always come in form of
53 pairs of devices (/dev/ptyXX and /dev/ttyXX), which are connected to each 53 pairs of devices (/dev/ptyXX and /dev/ttyXX), which are connected to each
54 other by the operating system. One may think of them as two serial devices 54 other by the operating system. One may think of them as two serial devices
55 linked by a null-modem cable. Being based on devices the number of 55 linked by a null-modem cable. Being based on devices the number of
56 simultanous instances of this class is (globally) limited by the number of 56 simultanous instances of this class is (globally) limited by the number of
57 those device pairs, which is 256. 57 those device pairs, which is 256.
58 58
59 Another technic are UNIX 98 PTY's. These are supported also, and prefered 59 Another technic are UNIX 98 PTY's. These are supported also, and prefered
60 over the (obsolete) predecessor. 60 over the (obsolete) predecessor.
61 61
62 There's a sinister ioctl(2), signal(2) and job control stuff 62 There's a sinister ioctl(2), signal(2) and job control stuff
63 nessesary to make everything work as it should. 63 nessesary to make everything work as it should.
64*/ 64*/
65 65
66 66
67#include <qfileinfo.h>
67#include <qapplication.h> 68#include <qapplication.h>
68#include <qsocketnotifier.h> 69#include <qsocketnotifier.h>
69#include <qstring.h> 70#include <qstring.h>
70 71
71#include <stdlib.h> 72#include <stdlib.h>
72#include <stdio.h> 73#include <stdio.h>
73#include <signal.h> 74#include <signal.h>
74#include <fcntl.h> 75#include <fcntl.h>
75#include <unistd.h> 76#include <unistd.h>
76#include <termios.h> 77#include <termios.h>
77#include <sys/types.h> 78#include <sys/types.h>
78#include <sys/ioctl.h> 79#include <sys/ioctl.h>
79#include <sys/wait.h> 80#include <sys/wait.h>
80 81
81#ifdef HAVE_OPENPTY 82#ifdef HAVE_OPENPTY
82#include <pty.h> 83#include <pty.h>
83#endif 84#endif
84 85
85#include "MyPty.h" 86#include "MyPty.h"
86 87
87 88
88#undef VERBOSE_DEBUG 89#undef VERBOSE_DEBUG
89 90
90 91
91/* -------------------------------------------------------------------------- */ 92/* -------------------------------------------------------------------------- */
92 93
93/*! 94/*!
94 Informs the client program about the 95 Informs the client program about the
95 actual size of the window. 96 actual size of the window.
96*/ 97*/
97 98
98void MyPty::setSize(int lines, int columns) 99void MyPty::setSize(int lines, int columns)
99{ 100{
100 struct winsize wsize; 101 struct winsize wsize;
101 wsize.ws_row = (unsigned short)lines; 102 wsize.ws_row = (unsigned short)lines;
102 wsize.ws_col = (unsigned short)columns; 103 wsize.ws_col = (unsigned short)columns;
103 if(fd < 0) return; 104 if(fd < 0) return;
104 ioctl(fd,TIOCSWINSZ,(char *)&wsize); 105 ioctl(fd,TIOCSWINSZ,(char *)&wsize);
105} 106}
106 107
107 108
108void MyPty::donePty() 109void MyPty::donePty()
109{ 110{
110 // This is code from the Qt DumbTerminal example 111 // This is code from the Qt DumbTerminal example
111 int status = 0; 112 int status = 0;
112 113
113 ::close(fd); 114 ::close(fd);
114 115
@@ -124,98 +125,100 @@ void MyPty::donePty()
124const char* MyPty::deviceName() 125const char* MyPty::deviceName()
125{ 126{
126 return ttynam; 127 return ttynam;
127} 128}
128 129
129 130
130void MyPty::error() 131void MyPty::error()
131{ 132{
132 // This is code from the Qt DumbTerminal example 133 // This is code from the Qt DumbTerminal example
133 donePty(); 134 donePty();
134} 135}
135 136
136 137
137/*! 138/*!
138 start the client program. 139 start the client program.
139*/ 140*/
140int MyPty::run(const char* cmd, QStrList &, const char*, int) 141int MyPty::run(const char* cmd, QStrList &, const char*, int)
141{ 142{
142 // This is code from the Qt DumbTerminal example 143 // This is code from the Qt DumbTerminal example
143 cpid = fork(); 144 cpid = fork();
144 145
145 if ( !cpid ) { 146 if ( !cpid ) {
146 // child - exec shell on tty 147 // child - exec shell on tty
147 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL); 148 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL);
148 int ttyfd = open(ttynam, O_RDWR); 149 int ttyfd = open(ttynam, O_RDWR);
149 dup2(ttyfd, STDIN_FILENO); 150 dup2(ttyfd, STDIN_FILENO);
150 dup2(ttyfd, STDOUT_FILENO); 151 dup2(ttyfd, STDOUT_FILENO);
151 dup2(ttyfd, STDERR_FILENO); 152 dup2(ttyfd, STDERR_FILENO);
152 // should be done with tty, so close it 153 // should be done with tty, so close it
153 close(ttyfd); 154 close(ttyfd);
154 static struct termios ttmode; 155 static struct termios ttmode;
155 if ( setsid() < 0 ) 156 if ( setsid() < 0 )
156 perror( "failed to set process group" ); 157 perror( "failed to set process group" );
157#if defined (TIOCSCTTY) 158#if defined (TIOCSCTTY)
158 // grabbed from APUE by Stevens 159 // grabbed from APUE by Stevens
159 ioctl(STDIN_FILENO, TIOCSCTTY, 0); 160 ioctl(STDIN_FILENO, TIOCSCTTY, 0);
160#endif 161#endif
161 tcgetattr( STDIN_FILENO, &ttmode ); 162 tcgetattr( STDIN_FILENO, &ttmode );
162 ttmode.c_cc[VINTR] = 3; 163 ttmode.c_cc[VINTR] = 3;
163 ttmode.c_cc[VERASE] = 8; 164 ttmode.c_cc[VERASE] = 8;
164 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode ); 165 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode );
165 setenv("TERM","vt100",1); 166 setenv("TERM","vt100",1);
166 setenv("COLORTERM","0",1); 167 setenv("COLORTERM","0",1);
167 168
168 if (getuid() == 0) { 169 if (getuid() == 0) {
169 char msg[] = "WARNING: You are running this shell as root!\n"; 170 char msg[] = "WARNING: You are running this shell as root!\n";
170 write(ttyfd, msg, sizeof(msg)); 171 write(ttyfd, msg, sizeof(msg));
171 } 172 }
172; //creates a login shell 173
173 execl(cmd, cmd, "--login", 0); 174 QString ccmd = "-"+QFileInfo(cmd).fileName(); //creates a login shell
175
176 execl(cmd, ccmd.latin1(), 0);
174 177
175 donePty(); 178 donePty();
176 exit(-1); 179 exit(-1);
177 } 180 }
178 181
179 // parent - continue as a widget 182 // parent - continue as a widget
180 QSocketNotifier* sn_r = new QSocketNotifier(fd,QSocketNotifier::Read,this); 183 QSocketNotifier* sn_r = new QSocketNotifier(fd,QSocketNotifier::Read,this);
181 QSocketNotifier* sn_e = new QSocketNotifier(fd,QSocketNotifier::Exception,this); 184 QSocketNotifier* sn_e = new QSocketNotifier(fd,QSocketNotifier::Exception,this);
182 connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty())); 185 connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty()));
183 connect(sn_e,SIGNAL(activated(int)),this,SLOT(error())); 186 connect(sn_e,SIGNAL(activated(int)),this,SLOT(error()));
184 187
185 return 0; 188 return 0;
186} 189}
187 190
188int MyPty::openPty() 191int MyPty::openPty()
189{ 192{
190 // This is code from the Qt DumbTerminal example 193 // This is code from the Qt DumbTerminal example
191 int ptyfd = -1; 194 int ptyfd = -1;
192 195
193#ifdef HAVE_OPENPTY 196#ifdef HAVE_OPENPTY
194 int ttyfd; 197 int ttyfd;
195 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) ) 198 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) )
196 ptyfd = -1; 199 ptyfd = -1;
197 else 200 else
198 close(ttyfd); // we open the ttynam ourselves. 201 close(ttyfd); // we open the ttynam ourselves.
199#else 202#else
200 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) { 203 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) {
201 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) { 204 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) {
202 sprintf(ptynam,"/dev/pty%c%c",*c0,*c1); 205 sprintf(ptynam,"/dev/pty%c%c",*c0,*c1);
203 sprintf(ttynam,"/dev/tty%c%c",*c0,*c1); 206 sprintf(ttynam,"/dev/tty%c%c",*c0,*c1);
204 if ((ptyfd = ::open(ptynam,O_RDWR)) >= 0) { 207 if ((ptyfd = ::open(ptynam,O_RDWR)) >= 0) {
205 if (geteuid() != 0 && !access(ttynam,R_OK|W_OK) == 0) { 208 if (geteuid() != 0 && !access(ttynam,R_OK|W_OK) == 0) {
206 ::close(ptyfd); 209 ::close(ptyfd);
207 ptyfd = -1; 210 ptyfd = -1;
208 } 211 }
209 } 212 }
210 } 213 }
211 } 214 }
212#endif 215#endif
213 216
214 if ( ptyfd < 0 ) { 217 if ( ptyfd < 0 ) {
215 qApp->exit(1); 218 qApp->exit(1);
216 return -1; 219 return -1;
217 } 220 }
218 221
219 return ptyfd; 222 return ptyfd;
220} 223}
221 224