summaryrefslogtreecommitdiff
authorharlekin <harlekin>2002-10-25 18:57:47 (UTC)
committer harlekin <harlekin>2002-10-25 18:57:47 (UTC)
commit1d3135677f1f49b9cc87ebf01f1c4eaab3c450f4 (patch) (unidiff)
tree63599d704e4f522393a613692369ff9c4a554eef
parent4151cc12a6c37cbec4bb6883204703eec2fb8648 (diff)
downloadopie-1d3135677f1f49b9cc87ebf01f1c4eaab3c450f4.zip
opie-1d3135677f1f49b9cc87ebf01f1c4eaab3c450f4.tar.gz
opie-1d3135677f1f49b9cc87ebf01f1c4eaab3c450f4.tar.bz2
is there is a real bash installed, take that instead of sh
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/MyPty.cpp6
1 files changed, 6 insertions, 0 deletions
diff --git a/noncore/apps/opie-console/MyPty.cpp b/noncore/apps/opie-console/MyPty.cpp
index 984e347..2570826 100644
--- a/noncore/apps/opie-console/MyPty.cpp
+++ b/noncore/apps/opie-console/MyPty.cpp
@@ -1,336 +1,342 @@
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#include <qfile.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 "procctl.h" 86#include "procctl.h"
86#include "MyPty.h" 87#include "MyPty.h"
87 88
88 89
89#undef VERBOSE_DEBUG 90#undef VERBOSE_DEBUG
90 91
91 92
92/* -------------------------------------------------------------------------- */ 93/* -------------------------------------------------------------------------- */
93 94
94/*! 95/*!
95 Informs the client program about the 96 Informs the client program about the
96 actual size of the window. 97 actual size of the window.
97*/ 98*/
98 99
99void MyPty::setSize(int lines, int columns) 100void MyPty::setSize(int lines, int columns)
100{ 101{
101 qWarning("setting size"); 102 qWarning("setting size");
102 struct winsize wsize; 103 struct winsize wsize;
103 wsize.ws_row = (unsigned short)lines; 104 wsize.ws_row = (unsigned short)lines;
104 wsize.ws_col = (unsigned short)columns; 105 wsize.ws_col = (unsigned short)columns;
105 if(m_fd < 0) return; 106 if(m_fd < 0) return;
106 ioctl(m_fd,TIOCSWINSZ,(char *)&wsize); 107 ioctl(m_fd,TIOCSWINSZ,(char *)&wsize);
107} 108}
108 109
109 110
110void MyPty::donePty() 111void MyPty::donePty()
111{ 112{
112 // This is code from the Qt DumbTerminal example 113 // This is code from the Qt DumbTerminal example
113 114
114 ::close(m_fd); 115 ::close(m_fd);
115 116
116 if (m_cpid) { 117 if (m_cpid) {
117 kill(m_cpid, SIGHUP); 118 kill(m_cpid, SIGHUP);
118 //waitpid(m_cpid, &status, 0); 119 //waitpid(m_cpid, &status, 0);
119 delete m_sn_e; 120 delete m_sn_e;
120 delete m_sn_r; 121 delete m_sn_r;
121 m_sn_e = 0l; 122 m_sn_e = 0l;
122 m_sn_r = 0l; 123 m_sn_r = 0l;
123 } 124 }
124 125
125 m_cpid = 0; 126 m_cpid = 0;
126 m_fd = -1; 127 m_fd = -1;
127// emit done(status); 128// emit done(status);
128} 129}
129 130
130 131
131const char* MyPty::deviceName() 132const char* MyPty::deviceName()
132{ 133{
133 return m_ttynam; 134 return m_ttynam;
134} 135}
135 136
136 137
137void MyPty::error() 138void MyPty::error()
138{ 139{
139 // This is code from the Qt DumbTerminal example 140 // This is code from the Qt DumbTerminal example
140 donePty(); 141 donePty();
141} 142}
142 143
143void MyPty::start() { 144void MyPty::start() {
144 char* cmd = "/bin/sh"; 145 char* cmd = "/bin/sh";
146
147 if ( QFile::exists( "/bin/bash" ) ) {
148 char* cmd = "/bin/bash";
149 }
150
145 QStrList lis; 151 QStrList lis;
146 int r =run(cmd, lis, 0, 0); 152 int r =run(cmd, lis, 0, 0);
147 r = r; 153 r = r;
148} 154}
149/*! 155/*!
150 start the client program. 156 start the client program.
151*/ 157*/
152int MyPty::run(const char* cmd, QStrList &, const char*, int) 158int MyPty::run(const char* cmd, QStrList &, const char*, int)
153{ 159{
154 // This is code from the Qt DumbTerminal example 160 // This is code from the Qt DumbTerminal example
155 m_cpid = fork(); 161 m_cpid = fork();
156 162
157 if ( !m_cpid ) { 163 if ( !m_cpid ) {
158 // child - exec shell on tty 164 // child - exec shell on tty
159 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL); 165 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL);
160 int ttyfd = ::open(m_ttynam, O_RDWR); 166 int ttyfd = ::open(m_ttynam, O_RDWR);
161 dup2(ttyfd, STDIN_FILENO); 167 dup2(ttyfd, STDIN_FILENO);
162 dup2(ttyfd, STDOUT_FILENO); 168 dup2(ttyfd, STDOUT_FILENO);
163 dup2(ttyfd, STDERR_FILENO); 169 dup2(ttyfd, STDERR_FILENO);
164 // should be done with tty, so close it 170 // should be done with tty, so close it
165 ::close(ttyfd); 171 ::close(ttyfd);
166 static struct termios ttmode; 172 static struct termios ttmode;
167 if ( setsid() < 0 ) 173 if ( setsid() < 0 )
168 perror( "failed to set process group" ); 174 perror( "failed to set process group" );
169#if defined (TIOCSCTTY) 175#if defined (TIOCSCTTY)
170 // grabbed from APUE by Stevens 176 // grabbed from APUE by Stevens
171 ioctl(STDIN_FILENO, TIOCSCTTY, 0); 177 ioctl(STDIN_FILENO, TIOCSCTTY, 0);
172#endif 178#endif
173 tcgetattr( STDIN_FILENO, &ttmode ); 179 tcgetattr( STDIN_FILENO, &ttmode );
174 ttmode.c_cc[VINTR] = 3; 180 ttmode.c_cc[VINTR] = 3;
175 ttmode.c_cc[VERASE] = 8; 181 ttmode.c_cc[VERASE] = 8;
176 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode ); 182 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode );
177 setenv("TERM",m_term,1); 183 setenv("TERM",m_term,1);
178 setenv("COLORTERM","0",1); 184 setenv("COLORTERM","0",1);
179 185
180 if (getuid() == 0) { 186 if (getuid() == 0) {
181 char msg[] = "WARNING: You are running this shell as root!\n"; 187 char msg[] = "WARNING: You are running this shell as root!\n";
182 write(ttyfd, msg, sizeof(msg)); 188 write(ttyfd, msg, sizeof(msg));
183 } 189 }
184 execl(cmd, cmd, 0); 190 execl(cmd, cmd, 0);
185 191
186 donePty(); 192 donePty();
187 exit(-1); 193 exit(-1);
188 } 194 }
189 195
190 // parent - continue as a widget 196 // parent - continue as a widget
191 delete m_sn_r; 197 delete m_sn_r;
192 m_sn_r = new QSocketNotifier(m_fd,QSocketNotifier::Read,this); 198 m_sn_r = new QSocketNotifier(m_fd,QSocketNotifier::Read,this);
193 delete m_sn_e; 199 delete m_sn_e;
194 m_sn_e = new QSocketNotifier(m_fd,QSocketNotifier::Exception,this); 200 m_sn_e = new QSocketNotifier(m_fd,QSocketNotifier::Exception,this);
195 connect(m_sn_r,SIGNAL(activated(int)),this,SLOT(readPty())); 201 connect(m_sn_r,SIGNAL(activated(int)),this,SLOT(readPty()));
196 connect(m_sn_e,SIGNAL(activated(int)),this,SLOT(error())); 202 connect(m_sn_e,SIGNAL(activated(int)),this,SLOT(error()));
197 203
198 return 0; 204 return 0;
199} 205}
200 206
201int MyPty::openPty() 207int MyPty::openPty()
202{ 208{
203 // This is code from the Qt DumbTerminal example 209 // This is code from the Qt DumbTerminal example
204 int ptyfd = -1; 210 int ptyfd = -1;
205 211
206#ifdef HAVE_OPENPTY 212#ifdef HAVE_OPENPTY
207 int ttyfd; 213 int ttyfd;
208 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) ) 214 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) )
209 ptyfd = -1; 215 ptyfd = -1;
210 else 216 else
211 close(ttyfd); // we open the ttynam ourselves. 217 close(ttyfd); // we open the ttynam ourselves.
212#else 218#else
213 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) { 219 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) {
214 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) { 220 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) {
215 sprintf(m_ptynam,"/dev/pty%c%c",*c0,*c1); 221 sprintf(m_ptynam,"/dev/pty%c%c",*c0,*c1);
216 sprintf(m_ttynam,"/dev/tty%c%c",*c0,*c1); 222 sprintf(m_ttynam,"/dev/tty%c%c",*c0,*c1);
217 if ((ptyfd = ::open(m_ptynam,O_RDWR)) >= 0) { 223 if ((ptyfd = ::open(m_ptynam,O_RDWR)) >= 0) {
218 if (geteuid() != 0 && !access(m_ttynam,R_OK|W_OK) == 0) { 224 if (geteuid() != 0 && !access(m_ttynam,R_OK|W_OK) == 0) {
219 ::close(ptyfd); 225 ::close(ptyfd);
220 ptyfd = -1; 226 ptyfd = -1;
221 } 227 }
222 } 228 }
223 } 229 }
224 } 230 }
225#endif 231#endif
226 232
227 if ( ptyfd < 0 ) { 233 if ( ptyfd < 0 ) {
228 //qApp->exit(1); 234 //qApp->exit(1);
229 return -1; 235 return -1;
230 } 236 }
231 237
232 return ptyfd; 238 return ptyfd;
233} 239}
234 240
235/*! 241/*!
236 Create an instance. 242 Create an instance.
237*/ 243*/
238MyPty::MyPty(const Profile& prof) : m_cpid(0) 244MyPty::MyPty(const Profile& prof) : m_cpid(0)
239{ 245{
240 246
241 int term = prof.readNumEntry("Terminal", Profile::VT100 ); 247 int term = prof.readNumEntry("Terminal", Profile::VT100 );
242 switch( term ) { 248 switch( term ) {
243 default: 249 default:
244 case Profile::VT100: 250 case Profile::VT100:
245 case Profile::VT102: 251 case Profile::VT102:
246 m_term = "vt100"; 252 m_term = "vt100";
247 break; 253 break;
248 case Profile::Linux: 254 case Profile::Linux:
249 m_term = "linux"; 255 m_term = "linux";
250 break; 256 break;
251 case Profile::XTerm: 257 case Profile::XTerm:
252 m_term = "xterm"; 258 m_term = "xterm";
253 break; 259 break;
254 } 260 }
255 m_sn_e = 0l; 261 m_sn_e = 0l;
256 m_sn_r = 0l; 262 m_sn_r = 0l;
257 m_fd = openPty(); 263 m_fd = openPty();
258 ProcCtl* ctl = ProcCtl::self(); 264 ProcCtl* ctl = ProcCtl::self();
259 Q_UNUSED(ctl); 265 Q_UNUSED(ctl);
260} 266}
261 267
262/*! 268/*!
263 Destructor. 269 Destructor.
264 Note that the related client program is not killed 270 Note that the related client program is not killed
265 (yet) when a instance is deleted. 271 (yet) when a instance is deleted.
266*/ 272*/
267MyPty::~MyPty() 273MyPty::~MyPty()
268{ 274{
269 donePty(); 275 donePty();
270} 276}
271QString MyPty::identifier()const { 277QString MyPty::identifier()const {
272 return QString::fromLatin1("term"); 278 return QString::fromLatin1("term");
273} 279}
274QString MyPty::name()const{ 280QString MyPty::name()const{
275 return identifier(); 281 return identifier();
276} 282}
277bool MyPty::open() { 283bool MyPty::open() {
278 if (m_fd < 0) 284 if (m_fd < 0)
279 m_fd = openPty(); 285 m_fd = openPty();
280 286
281 start(); 287 start();
282 return true; 288 return true;
283} 289}
284void MyPty::close() { 290void MyPty::close() {
285 donePty(); 291 donePty();
286 m_fd = openPty(); 292 m_fd = openPty();
287} 293}
288void MyPty::reload( const Profile& ) { 294void MyPty::reload( const Profile& ) {
289 295
290} 296}
291/*! sends len bytes through the line */ 297/*! sends len bytes through the line */
292void MyPty::send(const QByteArray& ar) 298void MyPty::send(const QByteArray& ar)
293{ 299{
294#ifdef VERBOSE_DEBUG 300#ifdef VERBOSE_DEBUG
295 // verbose debug 301 // verbose debug
296 printf("sending bytes:\n"); 302 printf("sending bytes:\n");
297 for (uint i = 0; i < ar.count(); i++) 303 for (uint i = 0; i < ar.count(); i++)
298 printf("%c", ar[i]); 304 printf("%c", ar[i]);
299 printf("\n"); 305 printf("\n");
300#endif 306#endif
301 307
302 ::write(m_fd, ar.data(), ar.count()); 308 ::write(m_fd, ar.data(), ar.count());
303} 309}
304 310
305/*! indicates that a block of data is received */ 311/*! indicates that a block of data is received */
306void MyPty::readPty() 312void MyPty::readPty()
307{ 313{
308 QByteArray buf(4096); 314 QByteArray buf(4096);
309 315
310 int len = ::read( m_fd, buf.data(), 4096 ); 316 int len = ::read( m_fd, buf.data(), 4096 );
311 317
312 if (len == -1 || len == 0) { 318 if (len == -1 || len == 0) {
313 donePty(); 319 donePty();
314 return; 320 return;
315 } 321 }
316 322
317 if (len < 0) 323 if (len < 0)
318 return; 324 return;
319 325
320 326
321 buf.resize(len); 327 buf.resize(len);
322 emit received(buf); 328 emit received(buf);
323 329
324#ifdef VERBOSE_DEBUG 330#ifdef VERBOSE_DEBUG
325 // verbose debug 331 // verbose debug
326 printf("read bytes:\n"); 332 printf("read bytes:\n");
327 for (uint i = 0; i < buf.count(); i++) 333 for (uint i = 0; i < buf.count(); i++)
328 printf("%c", buf[i]); 334 printf("%c", buf[i]);
329 printf("\n"); 335 printf("\n");
330#endif 336#endif
331 337
332} 338}
333QBitArray MyPty::supports()const { 339QBitArray MyPty::supports()const {
334 QBitArray ar(3); 340 QBitArray ar(3);
335 //autoconnect 341 //autoconnect
336 ar[0] = 1; 342 ar[0] = 1;