Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

MyPty.cpp

Go to the documentation of this file.
00001 /* -------------------------------------------------------------------------- */
00002 /*                                                                            */
00003 /* [MyPty.C]               Pseudo Terminal Device                             */
00004 /*                                                                            */
00005 /* -------------------------------------------------------------------------- */
00006 /*                                                                            */
00007 /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>            */
00008 /*                                                                            */
00009 /* This file is part of Konsole - an X terminal for KDE                       */
00010 /* -------------------------------------------------------------------------- */
00011 /*                        */
00012 /* Ported Konsole to Qt/Embedded                                              */
00013 /*                        */
00014 /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com>                  */
00015 /*                        */
00016 /* -------------------------------------------------------------------------- */
00017 
00018 /* If you're compiling konsole on non-Linux platforms and find
00019    problems that you can track down to this file, please have
00020    a look into ../README.ports, too.
00021 */
00022 
00067 #include <qfileinfo.h>
00068 #include <qapplication.h>
00069 #include <qsocketnotifier.h>
00070 
00071 #include <stdlib.h>
00072 #include <stdio.h>
00073 #include <signal.h>
00074 #include <fcntl.h>
00075 #include <unistd.h>
00076 #include <termios.h>
00077 #include <sys/types.h>
00078 #include <sys/ioctl.h>
00079 #include <sys/wait.h>
00080 
00081 #ifdef HAVE_OPENPTY
00082 #include <pty.h>
00083 #endif
00084 
00085 #include "MyPty.h"
00086 
00087 
00088 #undef VERBOSE_DEBUG
00089 
00090 
00091 /* -------------------------------------------------------------------------- */
00092 
00098 void MyPty::setSize(int lines, int columns)
00099 {
00100   struct winsize wsize;
00101   wsize.ws_row = (unsigned short)lines;
00102   wsize.ws_col = (unsigned short)columns;
00103   if(fd < 0) return;
00104   ioctl(fd,TIOCSWINSZ,(char *)&wsize);
00105 }
00106 
00107 
00108 void MyPty::donePty()
00109 {
00110     // This is code from the Qt DumbTerminal example
00111     int status = 0;
00112 
00113     ::close(fd);
00114 
00115     if (cpid) {
00116   kill(cpid, SIGHUP);
00117   waitpid(cpid, &status, 0);
00118     }
00119 
00120     emit done(status);
00121 }
00122 
00123 
00124 const char* MyPty::deviceName()
00125 {
00126     return ttynam;
00127 }
00128 
00129 
00130 void MyPty::error()
00131 {
00132     // This is code from the Qt DumbTerminal example
00133     donePty();
00134 }
00135 
00136 
00140 int MyPty::run(const char* cmd, QStrList &, const char*, int)
00141 {
00142       // This is code from the Qt DumbTerminal example
00143     cpid = fork();
00144 
00145     if ( !cpid ) {
00146   // child - exec shell on tty
00147   for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL);
00148 
00149   // attempt to keep apm driver from killing us on power on/off
00150   signal(SIGSTOP, SIG_IGN);
00151   signal(SIGCONT, SIG_IGN);
00152   signal(SIGTSTP, SIG_IGN);
00153 
00154   int ttyfd = open(ttynam, O_RDWR);
00155   dup2(ttyfd, STDIN_FILENO);
00156   dup2(ttyfd, STDOUT_FILENO);
00157   dup2(ttyfd, STDERR_FILENO);
00158   // should be done with tty, so close it
00159   close(ttyfd);
00160   static struct termios ttmode;
00161   if ( setsid() < 0 )
00162       perror( "failed to set process group" );
00163 #if defined (TIOCSCTTY)
00164   // grabbed from APUE by Stevens
00165   ioctl(STDIN_FILENO, TIOCSCTTY, 0);
00166 #endif
00167   tcgetattr( STDIN_FILENO, &ttmode );
00168   ttmode.c_cc[VINTR] = 3;
00169   ttmode.c_cc[VERASE] = 8;
00170   tcsetattr( STDIN_FILENO, TCSANOW, &ttmode );
00171 
00172         if(strlen(getenv("TERM"))<=0)
00173                         setenv("TERM","vt100",1);
00174   setenv("COLORTERM","0",1);
00175 
00176   if (getuid() == 0) {
00177       char msg[] = "WARNING: You are running this shell as root!\n";
00178       write(ttyfd, msg, sizeof(msg));
00179   }
00180 
00181   QString ccmd = "-"+QFileInfo(cmd).fileName(); //creates a login shell
00182 
00183   execl(cmd, ccmd.latin1(), 0);
00184 
00185   donePty();
00186   exit(-1);
00187     }
00188 
00189     // parent - continue as a widget
00190     QSocketNotifier* sn_r = new QSocketNotifier(fd,QSocketNotifier::Read,this);
00191     QSocketNotifier* sn_e = new QSocketNotifier(fd,QSocketNotifier::Exception,this);
00192     connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty()));
00193     connect(sn_e,SIGNAL(activated(int)),this,SLOT(error()));
00194 
00195     return 0;
00196 }
00197 
00198 int MyPty::openPty()
00199 {
00200     // This is code from the Qt DumbTerminal example
00201     int ptyfd = -1;
00202 
00203 #ifdef HAVE_OPENPTY
00204     int ttyfd;
00205     if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) )
00206   ptyfd = -1;
00207     else
00208   close(ttyfd); // we open the ttynam ourselves.
00209 #else
00210     for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) {
00211   for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) {
00212       sprintf(ptynam,"/dev/pty%c%c",*c0,*c1);
00213       sprintf(ttynam,"/dev/tty%c%c",*c0,*c1);
00214       if ((ptyfd = ::open(ptynam,O_RDWR)) >= 0) {
00215     if (geteuid() != 0 && !access(ttynam,R_OK|W_OK) == 0) {
00216         ::close(ptyfd);
00217         ptyfd = -1;
00218     }
00219       }
00220   }
00221     }
00222 #endif
00223 
00224     if ( ptyfd < 0 ) {
00225   qApp->exit(1);
00226   return -1;
00227     }
00228 
00229     return ptyfd;
00230 }
00231 
00235 MyPty::MyPty() : cpid(0)
00236 {
00237   fd = openPty();
00238 }
00239 
00245 MyPty::~MyPty()
00246 {
00247     donePty();
00248 }
00249 
00250 
00252 void MyPty::send_bytes(const char* s, int len)
00253 {
00254 
00255 #ifdef VERBOSE_DEBUG
00256   // verbose debug
00257   printf("sending bytes:\n");
00258   for (int i = 0; i < len; i++)
00259     printf("%c", s[i]);
00260   printf("\n");
00261 #endif
00262 
00263   ::write(fd, s, len);
00264 }
00265 
00267 void MyPty::readPty()
00268 {
00269   char buf[4096];
00270 
00271   int len = ::read( fd, buf, 4096 );
00272 
00273   if (len == -1)
00274      donePty();
00275 
00276   if (len < 0)
00277      return;
00278 
00279   emit block_in(buf,len);
00280 
00281 #ifdef VERBOSE_DEBUG
00282   // verbose debug
00283   printf("read bytes:\n");
00284   for (int i = 0; i < len; i++)
00285     printf("%c", buf[i]);
00286   printf("\n");
00287 #endif
00288 
00289 }
00290 

Generated on Sat Nov 5 16:15:26 2005 for OPIE by  doxygen 1.4.2