Qtopia library API Documentation

qprocess.cpp

00001 /****************************************************************************
00002 ** $Id: qprocess.cpp,v 1.1.1.1 2002/01/25 22:14:56 kergoth Exp $
00003 **
00004 ** Implementation of QProcess class
00005 **
00006 ** Created : 20000905
00007 **
00008 ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
00009 **
00010 ** This file is part of the kernel module of the Qt GUI Toolkit.
00011 **
00012 ** This file may be distributed under the terms of the Q Public License
00013 ** as defined by Trolltech AS of Norway and appearing in the file
00014 ** LICENSE.QPL included in the packaging of this file.
00015 **
00016 ** This file may be distributed and/or modified under the terms of the
00017 ** GNU General Public License version 2 as published by the Free Software
00018 ** Foundation and appearing in the file LICENSE.GPL included in the
00019 ** packaging of this file.
00020 **
00021 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
00022 ** licenses may use this file in accordance with the Qt Commercial License
00023 ** Agreement provided with the Software.
00024 **
00025 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00026 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00027 **
00028 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
00029 **   information about Qt Commercial License Agreements.
00030 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
00031 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00032 **
00033 ** Contact info@trolltech.com if any conditions of this licensing are
00034 ** not clear to you.
00035 **
00036 **********************************************************************/
00037 
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 
00041 #include "qprocess.h"
00042 
00043 #ifndef QT_NO_PROCESS
00044 
00045 #include "qapplication.h"
00046 
00047 
00048 //#define QT_QPROCESS_DEBUG
00049 
00050 
00090 QProcess::QProcess( QObject *parent, const char *name )
00091     : QObject( parent, name ), ioRedirection( FALSE ), notifyOnExit( FALSE ),
00092     wroteToStdinConnected( FALSE ),
00093     readStdoutCalled( FALSE ), readStderrCalled( FALSE ),
00094     comms( Stdin|Stdout|Stderr )
00095 {
00096     init();
00097 }
00098 
00108 QProcess::QProcess( const QString& arg0, QObject *parent, const char *name )
00109     : QObject( parent, name ), ioRedirection( FALSE ), notifyOnExit( FALSE ),
00110     wroteToStdinConnected( FALSE ),
00111     readStdoutCalled( FALSE ), readStderrCalled( FALSE ),
00112     comms( Stdin|Stdout|Stderr )
00113 {
00114     init();
00115     addArgument( arg0 );
00116 }
00117 
00129 QProcess::QProcess( const QStringList& args, QObject *parent, const char *name )
00130     : QObject( parent, name ), ioRedirection( FALSE ), notifyOnExit( FALSE ),
00131     wroteToStdinConnected( FALSE ),
00132     readStdoutCalled( FALSE ), readStderrCalled( FALSE ),
00133     comms( Stdin|Stdout|Stderr )
00134 {
00135     init();
00136     setArguments( args );
00137 }
00138 
00139 
00147 QStringList QProcess::arguments() const
00148 {
00149     return _arguments;
00150 }
00151 
00157 void QProcess::clearArguments()
00158 {
00159     _arguments.clear();
00160 }
00161 
00169 void QProcess::setArguments( const QStringList& args )
00170 {
00171     _arguments = args;
00172 }
00173 
00182 void QProcess::addArgument( const QString& arg )
00183 {
00184     _arguments.append( arg );
00185 }
00186 
00187 #ifndef QT_NO_DIR
00188 
00195 QDir QProcess::workingDirectory() const
00196 {
00197     return workingDir;
00198 }
00199 
00209 void QProcess::setWorkingDirectory( const QDir& dir )
00210 {
00211     workingDir = dir;
00212 }
00213 #endif //QT_NO_DIR
00214 
00220 int QProcess::communication() const
00221 {
00222     return comms;
00223 }
00224 
00234 void QProcess::setCommunication( int commFlags )
00235 {
00236     comms = commFlags;
00237 }
00238 
00246 bool QProcess::normalExit() const
00247 {
00248     // isRunning() has the side effect that it determines the exit status!
00249     if ( isRunning() )
00250     return FALSE;
00251     else
00252     return exitNormal;
00253 }
00254 
00266 int QProcess::exitStatus() const
00267 {
00268     // isRunning() has the side effect that it determines the exit status!
00269     if ( isRunning() )
00270     return 0;
00271     else
00272     return exitStat;
00273 }
00274 
00275 
00286 QByteArray QProcess::readStdout()
00287 {
00288     if ( readStdoutCalled ) {
00289     return QByteArray();
00290     }
00291     readStdoutCalled = TRUE;
00292 
00293     QByteArray buf = bufStdout()->copy();
00294     consumeBufStdout( -1 ); // consume everything
00295 
00296     readStdoutCalled = FALSE;
00297     return buf;
00298 }
00299 
00310 QByteArray QProcess::readStderr()
00311 {
00312     if ( readStderrCalled ) {
00313     return QByteArray();
00314     }
00315     readStderrCalled = TRUE;
00316 
00317     QByteArray buf = bufStderr()->copy();
00318     consumeBufStderr( -1 ); // consume everything
00319 
00320     readStderrCalled = FALSE;
00321     return buf;
00322 }
00323 
00330 bool QProcess::canReadLineStdout() const
00331 {
00332     QProcess *that = (QProcess*)this;
00333     return that->scanNewline( TRUE, 0 );
00334 }
00335 
00342 bool QProcess::canReadLineStderr() const
00343 {
00344     QProcess *that = (QProcess*)this;
00345     return that->scanNewline( FALSE, 0 );
00346 }
00347 
00355 QString QProcess::readLineStdout()
00356 {
00357     QByteArray a;
00358     QString s;
00359     if ( scanNewline( TRUE, &a ) ) {
00360     if ( a.isEmpty() )
00361         s = "";
00362     else
00363         s = QString( a );
00364     }
00365     return s;
00366 }
00367 
00375 QString QProcess::readLineStderr()
00376 {
00377     QByteArray a;
00378     QString s;
00379     if ( scanNewline( FALSE, &a ) ) {
00380     if ( a.isEmpty() )
00381         s = "";
00382     else
00383         s = QString( a );
00384     }
00385     return s;
00386 }
00387 
00393 bool QProcess::scanNewline( bool stdOut, QByteArray *store )
00394 {
00395     QByteArray *buf;
00396     if ( stdOut )
00397     buf = bufStdout();
00398     else
00399     buf = bufStderr();
00400     uint n = buf->size();
00401     uint i;
00402     for ( i=0; i<n; i++ ) {
00403     if ( buf->at(i) == '\n' ) {
00404         break;
00405     }
00406     }
00407     if ( i >= n )
00408     return FALSE;
00409 
00410     if ( store ) {
00411     uint lineLength = i;
00412     if ( lineLength>0 && buf->at(lineLength-1) == '\r' )
00413         lineLength--; // (if there are two \r, let one stay)
00414     store->resize( lineLength );
00415     memcpy( store->data(), buf->data(), lineLength );
00416     if ( stdOut )
00417         consumeBufStdout( i+1 );
00418     else
00419         consumeBufStderr( i+1 );
00420     }
00421     return TRUE;
00422 }
00423 
00474 bool QProcess::launch( const QByteArray& buf, QStringList *env )
00475 {
00476     if ( start( env ) ) {
00477     if ( !buf.isEmpty() ) {
00478         connect( this, SIGNAL(wroteToStdin()),
00479             this, SLOT(closeStdinLaunch()) );
00480         writeToStdin( buf );
00481     } else {
00482         closeStdin();
00483         emit launchFinished();
00484     }
00485     return TRUE;
00486     } else {
00487     emit launchFinished();
00488     return FALSE;
00489     }
00490 }
00491 
00497 bool QProcess::launch( const QString& buf, QStringList *env )
00498 {
00499     if ( start( env ) ) {
00500     if ( !buf.isEmpty() ) {
00501         connect( this, SIGNAL(wroteToStdin()),
00502             this, SLOT(closeStdinLaunch()) );
00503         writeToStdin( buf );
00504     } else {
00505         closeStdin();
00506         emit launchFinished();
00507     }
00508     return TRUE;
00509     } else {
00510     emit launchFinished();
00511     return FALSE;
00512     }
00513 }
00514 
00518 void QProcess::closeStdinLaunch()
00519 {
00520     disconnect( this, SIGNAL(wroteToStdin()),
00521         this, SLOT(closeStdinLaunch()) );
00522     closeStdin();
00523     emit launchFinished();
00524 }
00525 
00526 
00578 void QProcess::writeToStdin( const QString& buf )
00579 {
00580     QByteArray tmp = buf.local8Bit();
00581     tmp.resize( buf.length() );
00582     writeToStdin( tmp );
00583 }
00584 
00585 
00586 /*
00587  * Under Windows the implementation is not so nice: it is not that easy to
00588  * detect when one of the signals should be emitted; therefore there are some
00589  * timers that query the information.
00590  * To keep it a little efficient, use the timers only when they are needed.
00591  * They are needed, if you are interested in the signals. So use
00592  * connectNotify() and disconnectNotify() to keep track of your interest.
00593  */
00596 void QProcess::connectNotify( const char * signal )
00597 {
00598 #if defined(QT_QPROCESS_DEBUG)
00599     qDebug( "QProcess::connectNotify(): signal %s has been connected", signal );
00600 #endif
00601     if ( !ioRedirection )
00602     if ( qstrcmp( signal, SIGNAL(readyReadStdout()) )==0 ||
00603         qstrcmp( signal, SIGNAL(readyReadStderr()) )==0
00604        ) {
00605 #if defined(QT_QPROCESS_DEBUG)
00606         qDebug( "QProcess::connectNotify(): set ioRedirection to TRUE" );
00607 #endif
00608         setIoRedirection( TRUE );
00609         return;
00610     }
00611     if ( !notifyOnExit && qstrcmp( signal, SIGNAL(processExited()) )==0 ) {
00612 #if defined(QT_QPROCESS_DEBUG)
00613     qDebug( "QProcess::connectNotify(): set notifyOnExit to TRUE" );
00614 #endif
00615     setNotifyOnExit( TRUE );
00616     return;
00617     }
00618     if ( !wroteToStdinConnected && qstrcmp( signal, SIGNAL(wroteToStdin()) )==0 ) {
00619 #if defined(QT_QPROCESS_DEBUG)
00620     qDebug( "QProcess::connectNotify(): set wroteToStdinConnected to TRUE" );
00621 #endif
00622     setWroteStdinConnected( TRUE );
00623     return;
00624     }
00625 }
00626 
00629 void QProcess::disconnectNotify( const char * )
00630 {
00631     if ( ioRedirection &&
00632         receivers( SIGNAL(readyReadStdout()) ) ==0 &&
00633         receivers( SIGNAL(readyReadStderr()) ) ==0
00634         ) {
00635 #if defined(QT_QPROCESS_DEBUG)
00636     qDebug( "QProcess::disconnectNotify(): set ioRedirection to FALSE" );
00637 #endif
00638     setIoRedirection( FALSE );
00639     }
00640     if ( notifyOnExit && receivers( SIGNAL(processExited()) ) == 0 ) {
00641 #if defined(QT_QPROCESS_DEBUG)
00642     qDebug( "QProcess::disconnectNotify(): set notifyOnExit to FALSE" );
00643 #endif
00644     setNotifyOnExit( FALSE );
00645     }
00646     if ( wroteToStdinConnected && receivers( SIGNAL(wroteToStdin()) ) == 0 ) {
00647 #if defined(QT_QPROCESS_DEBUG)
00648     qDebug( "QProcess::disconnectNotify(): set wroteToStdinConnected to FALSE" );
00649 #endif
00650     setWroteStdinConnected( FALSE );
00651     }
00652 }
00653 
00654 #endif // QT_NO_PROCESS
KDE Logo
This file is part of the documentation for OPIE Version 1.5.5.
Documentation copyright © 1997-2003 the KDE developers. 2003 OPIE developers
Generated on Tue Feb 10 20:24:08 2004 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2001