summaryrefslogtreecommitdiff
authorerik <erik>2007-04-20 21:21:14 (UTC)
committer erik <erik>2007-04-20 21:21:14 (UTC)
commitd07beba6b9351c6b575235522781e3ce8495e578 (patch) (unidiff)
tree8c5d9cca84d79d7d3016ceb187a1a67a8adba662
parentfb862bdc6c9a6f5b6e7529823eb4b56cc7085a59 (diff)
downloadopie-d07beba6b9351c6b575235522781e3ce8495e578.zip
opie-d07beba6b9351c6b575235522781e3ce8495e578.tar.gz
opie-d07beba6b9351c6b575235522781e3ce8495e578.tar.bz2
additional info to a comment about pty mangling
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/apps/embeddedkonsole/MyPty.cpp2
1 files changed, 1 insertions, 1 deletions
diff --git a/core/apps/embeddedkonsole/MyPty.cpp b/core/apps/embeddedkonsole/MyPty.cpp
index 4b1ae59..c11889e 100644
--- a/core/apps/embeddedkonsole/MyPty.cpp
+++ b/core/apps/embeddedkonsole/MyPty.cpp
@@ -1,290 +1,290 @@
1/* -------------------------------------------------------------------------- */ 1/* -------------------------------------------------------------------------- */
2/* */ 2/* */
3/* [MyPty.C] Pseudo Terminal Device */ 3/* [MyPty.C] Pseudo Terminal Device */
4/* */ 4/* */
5/* -------------------------------------------------------------------------- */ 5/* -------------------------------------------------------------------------- */
6/* */ 6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ 7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */ 8/* */
9/* This file is part of Konsole - an X terminal for KDE */ 9/* This file is part of Konsole - an X terminal for KDE */
10/* -------------------------------------------------------------------------- */ 10/* -------------------------------------------------------------------------- */
11/* */ 11/* */
12/* Ported Konsole to Qt/Embedded */ 12/* Ported Konsole to Qt/Embedded */
13/* */ 13/* */
14/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ 14/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
15/* */ 15/* */
16/* -------------------------------------------------------------------------- */ 16/* -------------------------------------------------------------------------- */
17 17
18/* If you're compiling konsole on non-Linux platforms and find 18/* If you're compiling konsole on non-Linux platforms and find
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 <qfileinfo.h>
68#include <qapplication.h> 68#include <qapplication.h>
69#include <qsocketnotifier.h> 69#include <qsocketnotifier.h>
70 70
71#include <stdlib.h> 71#include <stdlib.h>
72#include <stdio.h> 72#include <stdio.h>
73#include <signal.h> 73#include <signal.h>
74#include <fcntl.h> 74#include <fcntl.h>
75#include <unistd.h> 75#include <unistd.h>
76#include <termios.h> 76#include <termios.h>
77#include <sys/types.h> 77#include <sys/types.h>
78#include <sys/ioctl.h> 78#include <sys/ioctl.h>
79#include <sys/wait.h> 79#include <sys/wait.h>
80 80
81#ifdef HAVE_OPENPTY 81#ifdef HAVE_OPENPTY
82#include <pty.h> 82#include <pty.h>
83#endif 83#endif
84 84
85#include "MyPty.h" 85#include "MyPty.h"
86 86
87 87
88#undef VERBOSE_DEBUG 88#undef VERBOSE_DEBUG
89 89
90 90
91/* -------------------------------------------------------------------------- */ 91/* -------------------------------------------------------------------------- */
92 92
93/*! 93/*!
94 Informs the client program about the 94 Informs the client program about the
95 actual size of the window. 95 actual size of the window.
96*/ 96*/
97 97
98void MyPty::setSize(int lines, int columns) 98void MyPty::setSize(int lines, int columns)
99{ 99{
100 struct winsize wsize; 100 struct winsize wsize;
101 wsize.ws_row = (unsigned short)lines; 101 wsize.ws_row = (unsigned short)lines;
102 wsize.ws_col = (unsigned short)columns; 102 wsize.ws_col = (unsigned short)columns;
103 if(fd < 0) return; 103 if(fd < 0) return;
104 ioctl(fd,TIOCSWINSZ,(char *)&wsize); 104 ioctl(fd,TIOCSWINSZ,(char *)&wsize);
105} 105}
106 106
107 107
108void MyPty::donePty() 108void MyPty::donePty()
109{ 109{
110 // This is code from the Qt DumbTerminal example 110 // This is code from the Qt DumbTerminal example
111 int status = 0; 111 int status = 0;
112 112
113 ::close(fd); 113 ::close(fd);
114 114
115 if (cpid) { 115 if (cpid) {
116 kill(cpid, SIGHUP); 116 kill(cpid, SIGHUP);
117 waitpid(cpid, &status, 0); 117 waitpid(cpid, &status, 0);
118 } 118 }
119 119
120 emit done(status); 120 emit done(status);
121} 121}
122 122
123 123
124const char* MyPty::deviceName() 124const char* MyPty::deviceName()
125{ 125{
126 return ttynam; 126 return ttynam;
127} 127}
128 128
129 129
130void MyPty::error() 130void MyPty::error()
131{ 131{
132 // This is code from the Qt DumbTerminal example 132 // This is code from the Qt DumbTerminal example
133 donePty(); 133 donePty();
134} 134}
135 135
136 136
137/*! 137/*!
138 start the client program. 138 start the client program.
139*/ 139*/
140int MyPty::run(const char* cmd, QStrList &, const char*, int) 140int MyPty::run(const char* cmd, QStrList &, const char*, int)
141{ 141{
142 // This is code from the Qt DumbTerminal example 142 // This is code from the Qt DumbTerminal example
143 cpid = fork(); 143 cpid = fork();
144 144
145 if ( !cpid ) { 145 if ( !cpid ) {
146 // child - exec shell on tty 146 // child - exec shell on tty
147 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL); 147 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL);
148 148
149 // attempt to keep apm driver from killing us on power on/off 149 // attempt to keep apm driver from killing us on power on/off
150 signal(SIGSTOP, SIG_IGN); 150 signal(SIGSTOP, SIG_IGN);
151 signal(SIGCONT, SIG_IGN); 151 signal(SIGCONT, SIG_IGN);
152 signal(SIGTSTP, SIG_IGN); 152 signal(SIGTSTP, SIG_IGN);
153 153
154 int ttyfd = open(ttynam, O_RDWR); 154 int ttyfd = open(ttynam, O_RDWR);
155 dup2(ttyfd, STDIN_FILENO); 155 dup2(ttyfd, STDIN_FILENO);
156 dup2(ttyfd, STDOUT_FILENO); 156 dup2(ttyfd, STDOUT_FILENO);
157 dup2(ttyfd, STDERR_FILENO); 157 dup2(ttyfd, STDERR_FILENO);
158 // should be done with tty, so close it 158 // should be done with tty, so close it
159 close(ttyfd); 159 close(ttyfd);
160 static struct termios ttmode; 160 static struct termios ttmode;
161 if ( setsid() < 0 ) 161 if ( setsid() < 0 )
162 perror( "failed to set process group" ); 162 perror( "failed to set process group" );
163#if defined (TIOCSCTTY) 163#if defined (TIOCSCTTY)
164 // grabbed from APUE by Stevens 164 // grabbed from APUE by Stevens (see section 9.6, should be page 246)
165 ioctl(STDIN_FILENO, TIOCSCTTY, 0); 165 ioctl(STDIN_FILENO, TIOCSCTTY, 0);
166#endif 166#endif
167 tcgetattr( STDIN_FILENO, &ttmode ); 167 tcgetattr( STDIN_FILENO, &ttmode );
168 ttmode.c_cc[VINTR] = 3; 168 ttmode.c_cc[VINTR] = 3;
169 ttmode.c_cc[VERASE] = 8; 169 ttmode.c_cc[VERASE] = 8;
170 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode ); 170 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode );
171 171
172 if(strlen(getenv("TERM"))<=0) 172 if(strlen(getenv("TERM"))<=0)
173 setenv("TERM","vt100",1); 173 setenv("TERM","vt100",1);
174 setenv("COLORTERM","0",1); 174 setenv("COLORTERM","0",1);
175 175
176 if (getuid() == 0) { 176 if (getuid() == 0) {
177 char msg[] = "WARNING: You are running this shell as root!\n"; 177 char msg[] = "WARNING: You are running this shell as root!\n";
178 write(ttyfd, msg, sizeof(msg)); 178 write(ttyfd, msg, sizeof(msg));
179 } 179 }
180 180
181 QString ccmd = "-"+QFileInfo(cmd).fileName(); //creates a login shell 181 QString ccmd = "-"+QFileInfo(cmd).fileName(); //creates a login shell
182 182
183 execl(cmd, ccmd.latin1(), 0); 183 execl(cmd, ccmd.latin1(), 0);
184 184
185 donePty(); 185 donePty();
186 exit(-1); 186 exit(-1);
187 } 187 }
188 188
189 // parent - continue as a widget 189 // parent - continue as a widget
190 QSocketNotifier* sn_r = new QSocketNotifier(fd,QSocketNotifier::Read,this); 190 QSocketNotifier* sn_r = new QSocketNotifier(fd,QSocketNotifier::Read,this);
191 QSocketNotifier* sn_e = new QSocketNotifier(fd,QSocketNotifier::Exception,this); 191 QSocketNotifier* sn_e = new QSocketNotifier(fd,QSocketNotifier::Exception,this);
192 connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty())); 192 connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty()));
193 connect(sn_e,SIGNAL(activated(int)),this,SLOT(error())); 193 connect(sn_e,SIGNAL(activated(int)),this,SLOT(error()));
194 194
195 return 0; 195 return 0;
196} 196}
197 197
198int MyPty::openPty() 198int MyPty::openPty()
199{ 199{
200 // This is code from the Qt DumbTerminal example 200 // This is code from the Qt DumbTerminal example
201 int ptyfd = -1; 201 int ptyfd = -1;
202 202
203#ifdef HAVE_OPENPTY 203#ifdef HAVE_OPENPTY
204 int ttyfd; 204 int ttyfd;
205 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) ) 205 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) )
206 ptyfd = -1; 206 ptyfd = -1;
207 else 207 else
208 close(ttyfd); // we open the ttynam ourselves. 208 close(ttyfd); // we open the ttynam ourselves.
209#else 209#else
210 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) { 210 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) {
211 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) { 211 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) {
212 sprintf(ptynam,"/dev/pty%c%c",*c0,*c1); 212 sprintf(ptynam,"/dev/pty%c%c",*c0,*c1);
213 sprintf(ttynam,"/dev/tty%c%c",*c0,*c1); 213 sprintf(ttynam,"/dev/tty%c%c",*c0,*c1);
214 if ((ptyfd = ::open(ptynam,O_RDWR)) >= 0) { 214 if ((ptyfd = ::open(ptynam,O_RDWR)) >= 0) {
215 if (geteuid() != 0 && !access(ttynam,R_OK|W_OK) == 0) { 215 if (geteuid() != 0 && !access(ttynam,R_OK|W_OK) == 0) {
216 ::close(ptyfd); 216 ::close(ptyfd);
217 ptyfd = -1; 217 ptyfd = -1;
218 } 218 }
219 } 219 }
220 } 220 }
221 } 221 }
222#endif 222#endif
223 223
224 if ( ptyfd < 0 ) { 224 if ( ptyfd < 0 ) {
225 qApp->exit(1); 225 qApp->exit(1);
226 return -1; 226 return -1;
227 } 227 }
228 228
229 return ptyfd; 229 return ptyfd;
230} 230}
231 231
232/*! 232/*!
233 Create an instance. 233 Create an instance.
234*/ 234*/
235MyPty::MyPty() : cpid(0) 235MyPty::MyPty() : cpid(0)
236{ 236{
237 fd = openPty(); 237 fd = openPty();
238} 238}
239 239
240/*! 240/*!
241 Destructor. 241 Destructor.
242 Note that the related client program is not killed 242 Note that the related client program is not killed
243 (yet) when a instance is deleted. 243 (yet) when a instance is deleted.
244*/ 244*/
245MyPty::~MyPty() 245MyPty::~MyPty()
246{ 246{
247 donePty(); 247 donePty();
248} 248}
249 249
250 250
251/*! sends len bytes through the line */ 251/*! sends len bytes through the line */
252void MyPty::send_bytes(const char* s, int len) 252void MyPty::send_bytes(const char* s, int len)
253{ 253{
254 254
255#ifdef VERBOSE_DEBUG 255#ifdef VERBOSE_DEBUG
256 // verbose debug 256 // verbose debug
257 printf("sending bytes:\n"); 257 printf("sending bytes:\n");
258 for (int i = 0; i < len; i++) 258 for (int i = 0; i < len; i++)
259 printf("%c", s[i]); 259 printf("%c", s[i]);
260 printf("\n"); 260 printf("\n");
261#endif 261#endif
262 262
263 ::write(fd, s, len); 263 ::write(fd, s, len);
264} 264}
265 265
266/*! indicates that a block of data is received */ 266/*! indicates that a block of data is received */
267void MyPty::readPty() 267void MyPty::readPty()
268{ 268{
269 char buf[4096]; 269 char buf[4096];
270 270
271 int len = ::read( fd, buf, 4096 ); 271 int len = ::read( fd, buf, 4096 );
272 272
273 if (len == -1) 273 if (len == -1)
274 donePty(); 274 donePty();
275 275
276 if (len < 0) 276 if (len < 0)
277 return; 277 return;
278 278
279 emit block_in(buf,len); 279 emit block_in(buf,len);
280 280
281#ifdef VERBOSE_DEBUG 281#ifdef VERBOSE_DEBUG
282 // verbose debug 282 // verbose debug
283 printf("read bytes:\n"); 283 printf("read bytes:\n");
284 for (int i = 0; i < len; i++) 284 for (int i = 0; i < len; i++)
285 printf("%c", buf[i]); 285 printf("%c", buf[i]);
286 printf("\n"); 286 printf("\n");
287#endif 287#endif
288 288
289} 289}
290 290