summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/MyPty.cpp22
-rw-r--r--noncore/apps/opie-console/procctl.cpp2
2 files changed, 18 insertions, 6 deletions
diff --git a/noncore/apps/opie-console/MyPty.cpp b/noncore/apps/opie-console/MyPty.cpp
index 10828b0..cacb4ce 100644
--- a/noncore/apps/opie-console/MyPty.cpp
+++ b/noncore/apps/opie-console/MyPty.cpp
@@ -61,95 +61,99 @@
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 "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(m_fd < 0) return; 104 if(m_fd < 0) return;
104 ioctl(m_fd,TIOCSWINSZ,(char *)&wsize); 105 ioctl(m_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(m_fd); 114 ::close(m_fd);
114 115
115 if (m_cpid) { 116 if (m_cpid) {
117 qWarning("killing!!!");
116 kill(m_cpid, SIGHUP); 118 kill(m_cpid, SIGHUP);
117 waitpid(m_cpid, &status, 0); 119 waitpid(m_cpid, &status, 0);
118 } 120 }
119 121
120 emit done(status); 122 m_cpid = 0;
123// emit done(status);
121} 124}
122 125
123 126
124const char* MyPty::deviceName() 127const char* MyPty::deviceName()
125{ 128{
126 return m_ttynam; 129 return m_ttynam;
127} 130}
128 131
129 132
130void MyPty::error() 133void MyPty::error()
131{ 134{
135 qWarning("error");
132 // This is code from the Qt DumbTerminal example 136 // This is code from the Qt DumbTerminal example
133 donePty(); 137 donePty();
134} 138}
135 139
136void MyPty::start() { 140void MyPty::start() {
137 char* cmd = "/bin/sh"; 141 char* cmd = "/bin/sh";
138 QStrList lis; 142 QStrList lis;
139 int r =run(cmd, lis, 0, 0); 143 int r =run(cmd, lis, 0, 0);
140 r = r; 144 r = r;
141} 145}
142/*! 146/*!
143 start the client program. 147 start the client program.
144*/ 148*/
145int MyPty::run(const char* cmd, QStrList &, const char*, int) 149int MyPty::run(const char* cmd, QStrList &, const char*, int)
146{ 150{
147 // This is code from the Qt DumbTerminal example 151 // This is code from the Qt DumbTerminal example
148 m_cpid = fork(); 152 m_cpid = fork();
149 153
150 if ( !m_cpid ) { 154 if ( !m_cpid ) {
151 // child - exec shell on tty 155 // child - exec shell on tty
152 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL); 156 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL);
153 int ttyfd = ::open(m_ttynam, O_RDWR); 157 int ttyfd = ::open(m_ttynam, O_RDWR);
154 dup2(ttyfd, STDIN_FILENO); 158 dup2(ttyfd, STDIN_FILENO);
155 dup2(ttyfd, STDOUT_FILENO); 159 dup2(ttyfd, STDOUT_FILENO);
@@ -161,139 +165,147 @@ int MyPty::run(const char* cmd, QStrList &, const char*, int)
161 perror( "failed to set process group" ); 165 perror( "failed to set process group" );
162#if defined (TIOCSCTTY) 166#if defined (TIOCSCTTY)
163 // grabbed from APUE by Stevens 167 // grabbed from APUE by Stevens
164 ioctl(STDIN_FILENO, TIOCSCTTY, 0); 168 ioctl(STDIN_FILENO, TIOCSCTTY, 0);
165#endif 169#endif
166 tcgetattr( STDIN_FILENO, &ttmode ); 170 tcgetattr( STDIN_FILENO, &ttmode );
167 ttmode.c_cc[VINTR] = 3; 171 ttmode.c_cc[VINTR] = 3;
168 ttmode.c_cc[VERASE] = 8; 172 ttmode.c_cc[VERASE] = 8;
169 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode ); 173 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode );
170 setenv("TERM","vt100",1); 174 setenv("TERM","vt100",1);
171 setenv("COLORTERM","0",1); 175 setenv("COLORTERM","0",1);
172 176
173 if (getuid() == 0) { 177 if (getuid() == 0) {
174 char msg[] = "WARNING: You are running this shell as root!\n"; 178 char msg[] = "WARNING: You are running this shell as root!\n";
175 write(ttyfd, msg, sizeof(msg)); 179 write(ttyfd, msg, sizeof(msg));
176 } 180 }
177 execl(cmd, cmd, 0); 181 execl(cmd, cmd, 0);
178 182
179 donePty(); 183 donePty();
180 exit(-1); 184 exit(-1);
181 } 185 }
182 186
183 // parent - continue as a widget 187 // parent - continue as a widget
184 QSocketNotifier* sn_r = new QSocketNotifier(m_fd,QSocketNotifier::Read,this); 188 QSocketNotifier* sn_r = new QSocketNotifier(m_fd,QSocketNotifier::Read,this);
185 QSocketNotifier* sn_e = new QSocketNotifier(m_fd,QSocketNotifier::Exception,this); 189// QSocketNotifier* sn_e = new QSocketNotifier(m_fd,QSocketNotifier::Exception,this);
186 connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty())); 190 connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty()));
187 connect(sn_e,SIGNAL(activated(int)),this,SLOT(error())); 191// connect(sn_e,SIGNAL(activated(int)),this,SLOT(error()));
188 192
189 return 0; 193 return 0;
190} 194}
191 195
192int MyPty::openPty() 196int MyPty::openPty()
193{ 197{
194 // This is code from the Qt DumbTerminal example 198 // This is code from the Qt DumbTerminal example
195 int ptyfd = -1; 199 int ptyfd = -1;
196 200
197#ifdef HAVE_OPENPTY 201#ifdef HAVE_OPENPTY
198 int ttyfd; 202 int ttyfd;
199 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) ) 203 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) )
200 ptyfd = -1; 204 ptyfd = -1;
201 else 205 else
202 close(ttyfd); // we open the ttynam ourselves. 206 close(ttyfd); // we open the ttynam ourselves.
203#else 207#else
204 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) { 208 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) {
205 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) { 209 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) {
206 sprintf(m_ptynam,"/dev/pty%c%c",*c0,*c1); 210 sprintf(m_ptynam,"/dev/pty%c%c",*c0,*c1);
207 sprintf(m_ttynam,"/dev/tty%c%c",*c0,*c1); 211 sprintf(m_ttynam,"/dev/tty%c%c",*c0,*c1);
208 if ((ptyfd = ::open(m_ptynam,O_RDWR)) >= 0) { 212 if ((ptyfd = ::open(m_ptynam,O_RDWR)) >= 0) {
209 if (geteuid() != 0 && !access(m_ttynam,R_OK|W_OK) == 0) { 213 if (geteuid() != 0 && !access(m_ttynam,R_OK|W_OK) == 0) {
210 ::close(ptyfd); 214 ::close(ptyfd);
211 ptyfd = -1; 215 ptyfd = -1;
212 } 216 }
213 } 217 }
214 } 218 }
215 } 219 }
216#endif 220#endif
217 221
218 if ( ptyfd < 0 ) { 222 if ( ptyfd < 0 ) {
219 qApp->exit(1); 223 qApp->exit(1);
220 return -1; 224 return -1;
221 } 225 }
222 226
223 return ptyfd; 227 return ptyfd;
224} 228}
225 229
226/*! 230/*!
227 Create an instance. 231 Create an instance.
228*/ 232*/
229MyPty::MyPty(const Profile&) : m_cpid(0) 233MyPty::MyPty(const Profile&) : m_cpid(0)
230{ 234{
231 m_fd = openPty(); 235 m_fd = openPty();
236 ProcCtl* ctl = ProcCtl::self();
232} 237}
233 238
234/*! 239/*!
235 Destructor. 240 Destructor.
236 Note that the related client program is not killed 241 Note that the related client program is not killed
237 (yet) when a instance is deleted. 242 (yet) when a instance is deleted.
238*/ 243*/
239MyPty::~MyPty() 244MyPty::~MyPty()
240{ 245{
241 donePty(); 246 donePty();
242} 247}
243QString MyPty::identifier()const { 248QString MyPty::identifier()const {
244 return QString::fromLatin1("term"); 249 return QString::fromLatin1("term");
245} 250}
246QString MyPty::name()const{ 251QString MyPty::name()const{
247 return identifier(); 252 return identifier();
248} 253}
249bool MyPty::open() { 254bool MyPty::open() {
250 start(); 255 start();
251 return true; 256 return true;
252} 257}
253void MyPty::close() { 258void MyPty::close() {
254 donePty(); 259 donePty();
255} 260}
256void MyPty::reload( const Profile& ) { 261void MyPty::reload( const Profile& ) {
257 262
258} 263}
259/*! sends len bytes through the line */ 264/*! sends len bytes through the line */
260void MyPty::send(const QByteArray& ar) 265void MyPty::send(const QByteArray& ar)
261{ 266{
262 267 qWarning("sending!");
263#ifdef VERBOSE_DEBUG 268#ifdef VERBOSE_DEBUG
264 // verbose debug 269 // verbose debug
265 printf("sending bytes:\n"); 270 printf("sending bytes:\n");
266 for (uint i = 0; i < ar.count(); i++) 271 for (uint i = 0; i < ar.count(); i++)
267 printf("%c", ar[i]); 272 printf("%c", ar[i]);
268 printf("\n"); 273 printf("\n");
269#endif 274#endif
270 275
271 ::write(m_fd, ar.data(), ar.count()); 276 ::write(m_fd, ar.data(), ar.count());
272} 277}
273 278
274/*! indicates that a block of data is received */ 279/*! indicates that a block of data is received */
275void MyPty::readPty() 280void MyPty::readPty()
276{ 281{
282 qWarning("read");
277 QByteArray buf(4096); 283 QByteArray buf(4096);
278 284
279 int len = ::read( m_fd, buf.data(), 4096 ); 285 int len = ::read( m_fd, buf.data(), 4096 );
280 286
281 if (len == -1) 287 if (len == -1 || len == 0) {
288 qWarning("donePty!!! now!");
282 donePty(); 289 donePty();
290 qWarning("return %s", sender()->className() );
291 delete sender();
292 return;
293 }
283 294
284 if (len < 0) 295 if (len < 0)
285 return; 296 return;
286 297
298
287 buf.resize(len); 299 buf.resize(len);
288 emit received(buf); 300 emit received(buf);
289 301
290#ifdef VERBOSE_DEBUG 302#ifdef VERBOSE_DEBUG
291 // verbose debug 303 // verbose debug
292 printf("read bytes:\n"); 304 printf("read bytes:\n");
293 for (uint i = 0; i < buf.count(); i++) 305 for (uint i = 0; i < buf.count(); i++)
294 printf("%c", buf[i]); 306 printf("%c", buf[i]);
295 printf("\n"); 307 printf("\n");
296#endif 308#endif
297 309
298} 310}
299 311
diff --git a/noncore/apps/opie-console/procctl.cpp b/noncore/apps/opie-console/procctl.cpp
index b0b6846..d1cfaf6 100644
--- a/noncore/apps/opie-console/procctl.cpp
+++ b/noncore/apps/opie-console/procctl.cpp
@@ -50,48 +50,48 @@ void ProcCtl::remove( pid_t pi ) {
50 if ( pi == con->pid ) { 50 if ( pi == con->pid ) {
51 forw->prev = con->prev; 51 forw->prev = con->prev;
52 delete con; 52 delete con;
53 return; 53 return;
54 } 54 }
55 55
56 forw = con; 56 forw = con;
57 con = con->prev; 57 con = con->prev;
58 } 58 }
59 59
60} 60}
61void ProcCtl::remove( ProcContainer con ) { 61void ProcCtl::remove( ProcContainer con ) {
62 remove( con.pid ); 62 remove( con.pid );
63} 63}
64int ProcCtl::status(pid_t pid )const{ 64int ProcCtl::status(pid_t pid )const{
65 ProcContainer *con = m_last; 65 ProcContainer *con = m_last;
66 while (con) { 66 while (con) {
67 if (con->pid == pid ) 67 if (con->pid == pid )
68 return con->status; 68 return con->status;
69 con = con->prev; 69 con = con->prev;
70 } 70 }
71 return -1; 71 return -1;
72} 72}
73void ProcCtl::signal_handler(int) { 73void ProcCtl::signal_handler(int) {
74 qWarning("signal handler"); 74 qWarning("signal handler in ProcCtl");
75 int status; 75 int status;
76 signal( SIGCHLD, signal_handler ); 76 signal( SIGCHLD, signal_handler );
77 pid_t pi = waitpid( -1, &status, WNOHANG ); 77 pid_t pi = waitpid( -1, &status, WNOHANG );
78 78
79 /* 79 /*
80 * find the container for pid 80 * find the container for pid
81 * 81 *
82 */ 82 */
83 if ( pi < 0 ) { 83 if ( pi < 0 ) {
84 return; 84 return;
85 } 85 }
86 86
87 ProcContainer* con = m_last; 87 ProcContainer* con = m_last;
88 while (con) { 88 while (con) {
89 if ( con->pid == pi ) { 89 if ( con->pid == pi ) {
90 con->status = status; 90 con->status = status;
91 char result = 1; 91 char result = 1;
92 /* give a 'signal' */ 92 /* give a 'signal' */
93 ::write(con->fd, &result, 1 ); 93 ::write(con->fd, &result, 1 );
94 } 94 }
95 con = con->prev; 95 con = con->prev;
96 } 96 }
97} 97}