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

filereceive.cpp

Go to the documentation of this file.
00001 #include <unistd.h>
00002 #include <fcntl.h>
00003 #include <signal.h>
00004 #include <errno.h>
00005 
00006 #include <qsocketnotifier.h>
00007 
00008 #include "io_layer.h"
00009 #include "procctl.h"
00010 #include "filereceive.h"
00011 
00012 FileReceive::FileReceive( Type t, IOLayer* lay, const QString& dir )
00013     : ReceiveLayer(lay, dir ), m_type( t )
00014 {
00015     m_fd = -1;
00016     m_not = 0l;
00017     m_proc = 0l;
00018 }
00019 FileReceive::~FileReceive() {
00020 }
00021 void FileReceive::receive() {
00022     receive( currentDir() );
00023 }
00024 void FileReceive::receive( const QString& dir ) {
00025     m_prog = -1;
00026     m_fd = layer()->rawIO();
00027     m_curDir = dir;
00028 
00029     if (pipe( m_comm ) < 0 )
00030         m_comm[0] = m_comm[1] = 0;
00031     if (pipe( m_info ) < 0 )
00032         m_info[0] = m_info[1] = 0;
00033 
00034     m_pid = fork();
00035     switch( m_pid ) {
00036     case -1:
00037         //emit error
00038         slotExec();
00039         break;
00040         /* child */
00041     case 0: {
00042         setupChild();
00043         char* typus =  NULL;
00044         switch(m_type ) {
00045         case SZ:
00046             break;
00047         case SX:
00048             typus = "-X";
00049             break;
00050         case SY:
00051             typus = "--ymodem";
00052             break;
00053         }
00054 
00055         /* we should never return from here */
00056         if( m_type == SX )
00057             // FIXME: file name should be configurable - currently we ensure it
00058             // doesn't get overwritten by -E (--rename)
00059             execlp("rz", "rz",  typus, "--overwrite", QObject::tr("SynchronizedFile").latin1(), NULL );
00060         else
00061             execlp("rz", "rz",  typus, "--overwrite", NULL );
00062 
00063         char resultByte = 1;
00064         if (m_info[1] )
00065             ::write(m_info[1], &resultByte, 1 );
00066 
00067         _exit( -1 );
00068         break;
00069     }
00070     default: {
00071         if ( m_info[1] )
00072             close( m_info[1] );
00073 
00074         if ( m_info[0] ) for (;;) {
00075             char resultByte; int len;
00076             len = read(m_info[0], &resultByte, 1 );
00077             /* len == 1 start up failed */
00078             if ( len == 1 ) {
00079                 emit error( StartError, tr("Could not start") );
00080                 return;
00081             }
00082             if ( len == -1 )
00083                 if ( (errno == ECHILD ) || (errno == EINTR ) )
00084                     continue;
00085 
00086             // len == 0 or something like this
00087             break;
00088         }
00089 
00090         if ( m_info[0] )
00091             close( m_info[0] );
00092 
00093         m_not = new QSocketNotifier(m_comm[0],  QSocketNotifier::Read );
00094         connect(m_not, SIGNAL(activated(int) ),
00095                 this, SLOT(slotRead() ) );
00096         if ( pipe(m_term) < 0 )
00097             m_term[0] = m_term[1] = 0;
00098 
00099         ProcCtl::self()->add(m_pid, m_term[1] );
00100         m_proc = new QSocketNotifier(m_term[0], QSocketNotifier::Read );
00101         connect(m_proc, SIGNAL(activated(int) ),
00102                 this, SLOT(slotExec() ) );
00103 
00104     }
00105         break;
00106 
00107     }
00108 
00109 }
00110 void FileReceive::cancel() {
00111     ::kill(m_pid, 9 );
00112 }
00113 void FileReceive::setupChild() {
00114     changeDir( currentDir() );
00115         /*
00116      * we do not want to read from our
00117      * information channel
00118      */
00119     if (m_info[0] )
00120         close(m_info[0] );
00121     /*
00122      * FD_CLOEXEC will close the
00123      * fd on successful exec
00124      */
00125     if (m_info[1] )
00126         fcntl(m_info[1], F_SETFD, FD_CLOEXEC );
00127 
00128     if (m_comm[0] )
00129         close( m_comm[0] );
00130     /*
00131      * now set the communication
00132      * m_fd STDIN_FILENO
00133      *      STDOUT_FILENO
00134      *      STDERR_FILENO
00135      */
00136     dup2( m_fd, STDIN_FILENO );
00137     dup2( m_fd, STDOUT_FILENO );
00138     dup2( m_comm[1], STDERR_FILENO );
00139 }
00140 void FileReceive::slotRead() {
00141     QByteArray ar(4096);
00142     int len = read(m_comm[0], ar.data(), 4096 );
00143     for (int i = 0; i < len; i++ ) {
00144         // printf("%c", ar[i] );
00145     }
00146     ar.resize( len );
00147     QString str( ar );
00148 }
00149 void FileReceive::slotExec() {
00150     char buf[2];
00151     ::read(m_term[0], buf, 1 );
00152     delete m_proc;
00153     delete m_not;
00154     m_not = m_proc = 0l;
00155     close( m_term[0] );
00156     close( m_term[1] );
00157     close( m_comm[0] );
00158     close( m_comm[1] );
00159     layer()->closeRawIO(m_fd);
00160     emit received(QString::null);
00161 
00162 }

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