-rw-r--r-- | noncore/apps/opie-console/MyPty.cpp | 10 | ||||
-rw-r--r-- | noncore/apps/opie-console/MyPty.h | 2 |
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 @@ -71,212 +71,216 @@ #include <stdlib.h> #include <stdio.h> #include <signal.h> #include <fcntl.h> #include <unistd.h> #include <termios.h> #include <sys/types.h> #include <sys/ioctl.h> #include <sys/wait.h> #ifdef HAVE_OPENPTY #include <pty.h> #endif #include "procctl.h" #include "MyPty.h" #undef VERBOSE_DEBUG /* -------------------------------------------------------------------------- */ /*! Informs the client program about the actual size of the window. */ void MyPty::setSize(int lines, int columns) { struct winsize wsize; wsize.ws_row = (unsigned short)lines; wsize.ws_col = (unsigned short)columns; if(m_fd < 0) return; ioctl(m_fd,TIOCSWINSZ,(char *)&wsize); } void MyPty::donePty() { // This is code from the Qt DumbTerminal example int status = 0; ::close(m_fd); if (m_cpid) { qWarning("killing!!!"); kill(m_cpid, SIGHUP); - waitpid(m_cpid, &status, 0); + //waitpid(m_cpid, &status, 0); + delete m_sn_e; + m_sn_e = 0l; } m_cpid = 0; // emit done(status); } const char* MyPty::deviceName() { return m_ttynam; } void MyPty::error() { qWarning("error"); // This is code from the Qt DumbTerminal example donePty(); } void MyPty::start() { char* cmd = "/bin/sh"; QStrList lis; int r =run(cmd, lis, 0, 0); r = r; } /*! start the client program. */ int MyPty::run(const char* cmd, QStrList &, const char*, int) { // This is code from the Qt DumbTerminal example m_cpid = fork(); if ( !m_cpid ) { // child - exec shell on tty for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL); int ttyfd = ::open(m_ttynam, O_RDWR); dup2(ttyfd, STDIN_FILENO); dup2(ttyfd, STDOUT_FILENO); dup2(ttyfd, STDERR_FILENO); // should be done with tty, so close it ::close(ttyfd); static struct termios ttmode; if ( setsid() < 0 ) perror( "failed to set process group" ); #if defined (TIOCSCTTY) // grabbed from APUE by Stevens ioctl(STDIN_FILENO, TIOCSCTTY, 0); #endif tcgetattr( STDIN_FILENO, &ttmode ); ttmode.c_cc[VINTR] = 3; ttmode.c_cc[VERASE] = 8; tcsetattr( STDIN_FILENO, TCSANOW, &ttmode ); setenv("TERM","vt100",1); setenv("COLORTERM","0",1); if (getuid() == 0) { char msg[] = "WARNING: You are running this shell as root!\n"; write(ttyfd, msg, sizeof(msg)); } execl(cmd, cmd, 0); donePty(); exit(-1); } // parent - continue as a widget QSocketNotifier* sn_r = new QSocketNotifier(m_fd,QSocketNotifier::Read,this); -// QSocketNotifier* sn_e = new QSocketNotifier(m_fd,QSocketNotifier::Exception,this); + delete m_sn_e; + m_sn_e = new QSocketNotifier(m_fd,QSocketNotifier::Exception,this); connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty())); -// connect(sn_e,SIGNAL(activated(int)),this,SLOT(error())); + connect(m_sn_e,SIGNAL(activated(int)),this,SLOT(error())); return 0; } int MyPty::openPty() { // This is code from the Qt DumbTerminal example int ptyfd = -1; #ifdef HAVE_OPENPTY int ttyfd; if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) ) ptyfd = -1; else close(ttyfd); // we open the ttynam ourselves. #else for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) { for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) { sprintf(m_ptynam,"/dev/pty%c%c",*c0,*c1); sprintf(m_ttynam,"/dev/tty%c%c",*c0,*c1); if ((ptyfd = ::open(m_ptynam,O_RDWR)) >= 0) { if (geteuid() != 0 && !access(m_ttynam,R_OK|W_OK) == 0) { ::close(ptyfd); ptyfd = -1; } } } } #endif if ( ptyfd < 0 ) { qApp->exit(1); return -1; } return ptyfd; } /*! Create an instance. */ MyPty::MyPty(const Profile&) : m_cpid(0) { + m_sn_e = 0l; m_fd = openPty(); ProcCtl* ctl = ProcCtl::self(); } /*! Destructor. Note that the related client program is not killed (yet) when a instance is deleted. */ MyPty::~MyPty() { donePty(); } QString MyPty::identifier()const { return QString::fromLatin1("term"); } QString MyPty::name()const{ return identifier(); } bool MyPty::open() { start(); return true; } void MyPty::close() { donePty(); } void MyPty::reload( const Profile& ) { } /*! sends len bytes through the line */ void MyPty::send(const QByteArray& ar) { qWarning("sending!"); #ifdef VERBOSE_DEBUG // verbose debug printf("sending bytes:\n"); for (uint i = 0; i < ar.count(); i++) printf("%c", ar[i]); printf("\n"); #endif ::write(m_fd, ar.data(), ar.count()); } /*! indicates that a block of data is received */ void MyPty::readPty() { qWarning("read"); 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 @@ /* -------------------------------------------------------------------------- */ /* */ /* [MyPty.h] Pseudo Terminal Device */ /* */ /* -------------------------------------------------------------------------- */ /* */ /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ /* */ /* This file is part of Konsole - an X terminal for KDE */ /* */ /* -------------------------------------------------------------------------- */ /* */ /* Ported Konsole to Qt/Embedded */ /* */ /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ /* */ /* -------------------------------------------------------------------------- */ /*! \file */ #ifndef MY_PTY_H #define MY_PTY_H #include <qobject.h> #include <qstrlist.h> #include "io_layer.h" class Profile; +class QSocketNotifier; class MyPty : public IOLayer { Q_OBJECT public: MyPty(const Profile&); ~MyPty(); QString identifier()const; QString name()const; public slots: /*! having a `run' separate from the constructor allows to make the necessary connections to the signals and slots of the instance before starting the execution of the client. */ void start(); int run(const char* pgm, QStrList & args , const char* term, int addutmp); bool open(); void close(); void reload( const Profile& ); void setSize(int lines, int columns); void error(); signals: /*! emitted when the client program terminates. \param status the wait(2) status code of the terminated client program. */ void done(int status); /*! emitted when a new block of data comes in. \param s - the data \param len - the length of the block */ void received(const QByteArray&); public slots: void send(const QByteArray& ); private: const char* deviceName(); protected slots: void readPty(); void donePty(); private: int openPty(); private: char m_ptynam[16]; // "/dev/ptyxx" | "/dev/ptmx" char m_ttynam[16]; // "/dev/ttyxx" | "/dev/pts/########..." int m_fd; int m_cpid; + QSocketNotifier* m_sn_e; }; #endif |