00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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
00249 if ( isRunning() )
00250 return FALSE;
00251 else
00252 return exitNormal;
00253 }
00254
00266 int QProcess::exitStatus() const
00267 {
00268
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 );
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 );
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--;
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
00588
00589
00590
00591
00592
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