-rw-r--r-- | core/apps/embeddedkonsole/MyPty.cpp | 7 |
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 | ||
98 | void MyPty::setSize(int lines, int columns) | 99 | void 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 | ||
108 | void MyPty::donePty() | 109 | void 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() | |||
124 | const char* MyPty::deviceName() | 125 | const char* MyPty::deviceName() |
125 | { | 126 | { |
126 | return ttynam; | 127 | return ttynam; |
127 | } | 128 | } |
128 | 129 | ||
129 | 130 | ||
130 | void MyPty::error() | 131 | void 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 | */ |
140 | int MyPty::run(const char* cmd, QStrList &, const char*, int) | 141 | int 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 | ||
188 | int MyPty::openPty() | 191 | int 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 | ||