summaryrefslogtreecommitdiff
authorzecke <zecke>2002-10-15 01:14:17 (UTC)
committer zecke <zecke>2002-10-15 01:14:17 (UTC)
commite0efd37513192d9a17fa9a9f46bbaed0ca38029c (patch) (unidiff)
tree04163d93fc4c4185d322912e9430eff9b36b71cc
parentb12b38a00c66ddc100f3fff75478539b8b797928 (diff)
downloadopie-e0efd37513192d9a17fa9a9f46bbaed0ca38029c.zip
opie-e0efd37513192d9a17fa9a9f46bbaed0ca38029c.tar.gz
opie-e0efd37513192d9a17fa9a9f46bbaed0ca38029c.tar.bz2
The right way to deal with the pipe
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/MyPty.cpp10
-rw-r--r--noncore/apps/opie-console/MyPty.h2
2 files changed, 9 insertions, 3 deletions
diff --git a/noncore/apps/opie-console/MyPty.cpp b/noncore/apps/opie-console/MyPty.cpp
index cacb4ce..ae01392 100644
--- a/noncore/apps/opie-console/MyPty.cpp
+++ b/noncore/apps/opie-console/MyPty.cpp
@@ -1,311 +1,315 @@
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 <qapplication.h> 67#include <qapplication.h>
68#include <qsocketnotifier.h> 68#include <qsocketnotifier.h>
69#include <qstring.h> 69#include <qstring.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 "procctl.h" 85#include "procctl.h"
86#include "MyPty.h" 86#include "MyPty.h"
87 87
88 88
89#undef VERBOSE_DEBUG 89#undef VERBOSE_DEBUG
90 90
91 91
92/* -------------------------------------------------------------------------- */ 92/* -------------------------------------------------------------------------- */
93 93
94/*! 94/*!
95 Informs the client program about the 95 Informs the client program about the
96 actual size of the window. 96 actual size of the window.
97*/ 97*/
98 98
99void MyPty::setSize(int lines, int columns) 99void MyPty::setSize(int lines, int columns)
100{ 100{
101 struct winsize wsize; 101 struct winsize wsize;
102 wsize.ws_row = (unsigned short)lines; 102 wsize.ws_row = (unsigned short)lines;
103 wsize.ws_col = (unsigned short)columns; 103 wsize.ws_col = (unsigned short)columns;
104 if(m_fd < 0) return; 104 if(m_fd < 0) return;
105 ioctl(m_fd,TIOCSWINSZ,(char *)&wsize); 105 ioctl(m_fd,TIOCSWINSZ,(char *)&wsize);
106} 106}
107 107
108 108
109void MyPty::donePty() 109void MyPty::donePty()
110{ 110{
111 // This is code from the Qt DumbTerminal example 111 // This is code from the Qt DumbTerminal example
112 int status = 0; 112 int status = 0;
113 113
114 ::close(m_fd); 114 ::close(m_fd);
115 115
116 if (m_cpid) { 116 if (m_cpid) {
117 qWarning("killing!!!"); 117 qWarning("killing!!!");
118 kill(m_cpid, SIGHUP); 118 kill(m_cpid, SIGHUP);
119 waitpid(m_cpid, &status, 0); 119 //waitpid(m_cpid, &status, 0);
120 delete m_sn_e;
121 m_sn_e = 0l;
120 } 122 }
121 123
122 m_cpid = 0; 124 m_cpid = 0;
123// emit done(status); 125// emit done(status);
124} 126}
125 127
126 128
127const char* MyPty::deviceName() 129const char* MyPty::deviceName()
128{ 130{
129 return m_ttynam; 131 return m_ttynam;
130} 132}
131 133
132 134
133void MyPty::error() 135void MyPty::error()
134{ 136{
135 qWarning("error"); 137 qWarning("error");
136 // This is code from the Qt DumbTerminal example 138 // This is code from the Qt DumbTerminal example
137 donePty(); 139 donePty();
138} 140}
139 141
140void MyPty::start() { 142void MyPty::start() {
141 char* cmd = "/bin/sh"; 143 char* cmd = "/bin/sh";
142 QStrList lis; 144 QStrList lis;
143 int r =run(cmd, lis, 0, 0); 145 int r =run(cmd, lis, 0, 0);
144 r = r; 146 r = r;
145} 147}
146/*! 148/*!
147 start the client program. 149 start the client program.
148*/ 150*/
149int MyPty::run(const char* cmd, QStrList &, const char*, int) 151int MyPty::run(const char* cmd, QStrList &, const char*, int)
150{ 152{
151 // This is code from the Qt DumbTerminal example 153 // This is code from the Qt DumbTerminal example
152 m_cpid = fork(); 154 m_cpid = fork();
153 155
154 if ( !m_cpid ) { 156 if ( !m_cpid ) {
155 // child - exec shell on tty 157 // child - exec shell on tty
156 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL); 158 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL);
157 int ttyfd = ::open(m_ttynam, O_RDWR); 159 int ttyfd = ::open(m_ttynam, O_RDWR);
158 dup2(ttyfd, STDIN_FILENO); 160 dup2(ttyfd, STDIN_FILENO);
159 dup2(ttyfd, STDOUT_FILENO); 161 dup2(ttyfd, STDOUT_FILENO);
160 dup2(ttyfd, STDERR_FILENO); 162 dup2(ttyfd, STDERR_FILENO);
161 // should be done with tty, so close it 163 // should be done with tty, so close it
162 ::close(ttyfd); 164 ::close(ttyfd);
163 static struct termios ttmode; 165 static struct termios ttmode;
164 if ( setsid() < 0 ) 166 if ( setsid() < 0 )
165 perror( "failed to set process group" ); 167 perror( "failed to set process group" );
166#if defined (TIOCSCTTY) 168#if defined (TIOCSCTTY)
167 // grabbed from APUE by Stevens 169 // grabbed from APUE by Stevens
168 ioctl(STDIN_FILENO, TIOCSCTTY, 0); 170 ioctl(STDIN_FILENO, TIOCSCTTY, 0);
169#endif 171#endif
170 tcgetattr( STDIN_FILENO, &ttmode ); 172 tcgetattr( STDIN_FILENO, &ttmode );
171 ttmode.c_cc[VINTR] = 3; 173 ttmode.c_cc[VINTR] = 3;
172 ttmode.c_cc[VERASE] = 8; 174 ttmode.c_cc[VERASE] = 8;
173 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode ); 175 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode );
174 setenv("TERM","vt100",1); 176 setenv("TERM","vt100",1);
175 setenv("COLORTERM","0",1); 177 setenv("COLORTERM","0",1);
176 178
177 if (getuid() == 0) { 179 if (getuid() == 0) {
178 char msg[] = "WARNING: You are running this shell as root!\n"; 180 char msg[] = "WARNING: You are running this shell as root!\n";
179 write(ttyfd, msg, sizeof(msg)); 181 write(ttyfd, msg, sizeof(msg));
180 } 182 }
181 execl(cmd, cmd, 0); 183 execl(cmd, cmd, 0);
182 184
183 donePty(); 185 donePty();
184 exit(-1); 186 exit(-1);
185 } 187 }
186 188
187 // parent - continue as a widget 189 // parent - continue as a widget
188 QSocketNotifier* sn_r = new QSocketNotifier(m_fd,QSocketNotifier::Read,this); 190 QSocketNotifier* sn_r = new QSocketNotifier(m_fd,QSocketNotifier::Read,this);
189// QSocketNotifier* sn_e = new QSocketNotifier(m_fd,QSocketNotifier::Exception,this); 191 delete m_sn_e;
192 m_sn_e = new QSocketNotifier(m_fd,QSocketNotifier::Exception,this);
190 connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty())); 193 connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty()));
191// connect(sn_e,SIGNAL(activated(int)),this,SLOT(error())); 194 connect(m_sn_e,SIGNAL(activated(int)),this,SLOT(error()));
192 195
193 return 0; 196 return 0;
194} 197}
195 198
196int MyPty::openPty() 199int MyPty::openPty()
197{ 200{
198 // This is code from the Qt DumbTerminal example 201 // This is code from the Qt DumbTerminal example
199 int ptyfd = -1; 202 int ptyfd = -1;
200 203
201#ifdef HAVE_OPENPTY 204#ifdef HAVE_OPENPTY
202 int ttyfd; 205 int ttyfd;
203 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) ) 206 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) )
204 ptyfd = -1; 207 ptyfd = -1;
205 else 208 else
206 close(ttyfd); // we open the ttynam ourselves. 209 close(ttyfd); // we open the ttynam ourselves.
207#else 210#else
208 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) { 211 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) {
209 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) { 212 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) {
210 sprintf(m_ptynam,"/dev/pty%c%c",*c0,*c1); 213 sprintf(m_ptynam,"/dev/pty%c%c",*c0,*c1);
211 sprintf(m_ttynam,"/dev/tty%c%c",*c0,*c1); 214 sprintf(m_ttynam,"/dev/tty%c%c",*c0,*c1);
212 if ((ptyfd = ::open(m_ptynam,O_RDWR)) >= 0) { 215 if ((ptyfd = ::open(m_ptynam,O_RDWR)) >= 0) {
213 if (geteuid() != 0 && !access(m_ttynam,R_OK|W_OK) == 0) { 216 if (geteuid() != 0 && !access(m_ttynam,R_OK|W_OK) == 0) {
214 ::close(ptyfd); 217 ::close(ptyfd);
215 ptyfd = -1; 218 ptyfd = -1;
216 } 219 }
217 } 220 }
218 } 221 }
219 } 222 }
220#endif 223#endif
221 224
222 if ( ptyfd < 0 ) { 225 if ( ptyfd < 0 ) {
223 qApp->exit(1); 226 qApp->exit(1);
224 return -1; 227 return -1;
225 } 228 }
226 229
227 return ptyfd; 230 return ptyfd;
228} 231}
229 232
230/*! 233/*!
231 Create an instance. 234 Create an instance.
232*/ 235*/
233MyPty::MyPty(const Profile&) : m_cpid(0) 236MyPty::MyPty(const Profile&) : m_cpid(0)
234{ 237{
238 m_sn_e = 0l;
235 m_fd = openPty(); 239 m_fd = openPty();
236 ProcCtl* ctl = ProcCtl::self(); 240 ProcCtl* ctl = ProcCtl::self();
237} 241}
238 242
239/*! 243/*!
240 Destructor. 244 Destructor.
241 Note that the related client program is not killed 245 Note that the related client program is not killed
242 (yet) when a instance is deleted. 246 (yet) when a instance is deleted.
243*/ 247*/
244MyPty::~MyPty() 248MyPty::~MyPty()
245{ 249{
246 donePty(); 250 donePty();
247} 251}
248QString MyPty::identifier()const { 252QString MyPty::identifier()const {
249 return QString::fromLatin1("term"); 253 return QString::fromLatin1("term");
250} 254}
251QString MyPty::name()const{ 255QString MyPty::name()const{
252 return identifier(); 256 return identifier();
253} 257}
254bool MyPty::open() { 258bool MyPty::open() {
255 start(); 259 start();
256 return true; 260 return true;
257} 261}
258void MyPty::close() { 262void MyPty::close() {
259 donePty(); 263 donePty();
260} 264}
261void MyPty::reload( const Profile& ) { 265void MyPty::reload( const Profile& ) {
262 266
263} 267}
264/*! sends len bytes through the line */ 268/*! sends len bytes through the line */
265void MyPty::send(const QByteArray& ar) 269void MyPty::send(const QByteArray& ar)
266{ 270{
267 qWarning("sending!"); 271 qWarning("sending!");
268#ifdef VERBOSE_DEBUG 272#ifdef VERBOSE_DEBUG
269 // verbose debug 273 // verbose debug
270 printf("sending bytes:\n"); 274 printf("sending bytes:\n");
271 for (uint i = 0; i < ar.count(); i++) 275 for (uint i = 0; i < ar.count(); i++)
272 printf("%c", ar[i]); 276 printf("%c", ar[i]);
273 printf("\n"); 277 printf("\n");
274#endif 278#endif
275 279
276 ::write(m_fd, ar.data(), ar.count()); 280 ::write(m_fd, ar.data(), ar.count());
277} 281}
278 282
279/*! indicates that a block of data is received */ 283/*! indicates that a block of data is received */
280void MyPty::readPty() 284void MyPty::readPty()
281{ 285{
282 qWarning("read"); 286 qWarning("read");
283 QByteArray buf(4096); 287 QByteArray buf(4096);
284 288
285 int len = ::read( m_fd, buf.data(), 4096 ); 289 int len = ::read( m_fd, buf.data(), 4096 );
286 290
287 if (len == -1 || len == 0) { 291 if (len == -1 || len == 0) {
288 qWarning("donePty!!! now!"); 292 qWarning("donePty!!! now!");
289 donePty(); 293 donePty();
290 qWarning("return %s", sender()->className() ); 294 qWarning("return %s", sender()->className() );
291 delete sender(); 295 delete sender();
292 return; 296 return;
293 } 297 }
294 298
295 if (len < 0) 299 if (len < 0)
296 return; 300 return;
297 301
298 302
299 buf.resize(len); 303 buf.resize(len);
300 emit received(buf); 304 emit received(buf);
301 305
302#ifdef VERBOSE_DEBUG 306#ifdef VERBOSE_DEBUG
303 // verbose debug 307 // verbose debug
304 printf("read bytes:\n"); 308 printf("read bytes:\n");
305 for (uint i = 0; i < buf.count(); i++) 309 for (uint i = 0; i < buf.count(); i++)
306 printf("%c", buf[i]); 310 printf("%c", buf[i]);
307 printf("\n"); 311 printf("\n");
308#endif 312#endif
309 313
310} 314}
311 315
diff --git a/noncore/apps/opie-console/MyPty.h b/noncore/apps/opie-console/MyPty.h
index 9231a8a..3166fa0 100644
--- a/noncore/apps/opie-console/MyPty.h
+++ b/noncore/apps/opie-console/MyPty.h
@@ -1,95 +1,97 @@
1/* -------------------------------------------------------------------------- */ 1/* -------------------------------------------------------------------------- */
2/* */ 2/* */
3/* [MyPty.h] Pseudo Terminal Device */ 3/* [MyPty.h] 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 /* */ 12 /* */
13/* Ported Konsole to Qt/Embedded */ 13/* Ported Konsole to Qt/Embedded */
14 /* */ 14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ 15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */ 16 /* */
17/* -------------------------------------------------------------------------- */ 17/* -------------------------------------------------------------------------- */
18 18
19/*! \file 19/*! \file
20*/ 20*/
21 21
22#ifndef MY_PTY_H 22#ifndef MY_PTY_H
23#define MY_PTY_H 23#define MY_PTY_H
24 24
25#include <qobject.h> 25#include <qobject.h>
26#include <qstrlist.h> 26#include <qstrlist.h>
27 27
28#include "io_layer.h" 28#include "io_layer.h"
29 29
30class Profile; 30class Profile;
31class QSocketNotifier;
31class MyPty : public IOLayer 32class MyPty : public IOLayer
32{ 33{
33 Q_OBJECT 34 Q_OBJECT
34public: 35public:
35 36
36 MyPty(const Profile&); 37 MyPty(const Profile&);
37 ~MyPty(); 38 ~MyPty();
38 39
39 40
40 41
41 QString identifier()const; 42 QString identifier()const;
42 QString name()const; 43 QString name()const;
43 44
44 public slots: 45 public slots:
45 /*! 46 /*!
46 having a `run' separate from the constructor allows to make 47 having a `run' separate from the constructor allows to make
47 the necessary connections to the signals and slots of the 48 the necessary connections to the signals and slots of the
48 instance before starting the execution of the client. 49 instance before starting the execution of the client.
49 */ 50 */
50 void start(); 51 void start();
51 int run(const char* pgm, QStrList & args , const char* term, int addutmp); 52 int run(const char* pgm, QStrList & args , const char* term, int addutmp);
52 bool open(); 53 bool open();
53 void close(); 54 void close();
54 void reload( const Profile& ); 55 void reload( const Profile& );
55 void setSize(int lines, int columns); 56 void setSize(int lines, int columns);
56 void error(); 57 void error();
57 58
58 signals: 59 signals:
59 60
60 /*! 61 /*!
61 emitted when the client program terminates. 62 emitted when the client program terminates.
62 \param status the wait(2) status code of the terminated client program. 63 \param status the wait(2) status code of the terminated client program.
63 */ 64 */
64 void done(int status); 65 void done(int status);
65 66
66 /*! 67 /*!
67 emitted when a new block of data comes in. 68 emitted when a new block of data comes in.
68 \param s - the data 69 \param s - the data
69 \param len - the length of the block 70 \param len - the length of the block
70 */ 71 */
71 void received(const QByteArray&); 72 void received(const QByteArray&);
72 73
73 public slots: 74 public slots:
74 75
75 void send(const QByteArray& ); 76 void send(const QByteArray& );
76 77
77private: 78private:
78 const char* deviceName(); 79 const char* deviceName();
79 80
80protected slots: 81protected slots:
81 void readPty(); 82 void readPty();
82 void donePty(); 83 void donePty();
83 84
84private: 85private:
85 int openPty(); 86 int openPty();
86 87
87private: 88private:
88 89
89 char m_ptynam[16]; // "/dev/ptyxx" | "/dev/ptmx" 90 char m_ptynam[16]; // "/dev/ptyxx" | "/dev/ptmx"
90 char m_ttynam[16]; // "/dev/ttyxx" | "/dev/pts/########..." 91 char m_ttynam[16]; // "/dev/ttyxx" | "/dev/pts/########..."
91 int m_fd; 92 int m_fd;
92 int m_cpid; 93 int m_cpid;
94 QSocketNotifier* m_sn_e;
93}; 95};
94 96
95#endif 97#endif