00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023
00024 #include "qprocess.h"
00025
00026 #ifndef QT_NO_PROCESS
00027
00028 #include "qapplication.h"
00029
00030
00031
00032
00033
00075 QProcess::QProcess( QObject *parent, const char *name )
00076 : QObject( parent, name ), ioRedirection( FALSE ), notifyOnExit( FALSE ),
00077 wroteToStdinConnected( FALSE ),
00078 readStdoutCalled( FALSE ), readStderrCalled( FALSE ),
00079 comms( Stdin|Stdout|Stderr )
00080 {
00081 init();
00082 }
00083
00093 QProcess::QProcess( const QString& arg0, QObject *parent, const char *name )
00094 : QObject( parent, name ), ioRedirection( FALSE ), notifyOnExit( FALSE ),
00095 wroteToStdinConnected( FALSE ),
00096 readStdoutCalled( FALSE ), readStderrCalled( FALSE ),
00097 comms( Stdin|Stdout|Stderr )
00098 {
00099 init();
00100 addArgument( arg0 );
00101 }
00102
00114 QProcess::QProcess( const QStringList& args, QObject *parent, const char *name )
00115 : QObject( parent, name ), ioRedirection( FALSE ), notifyOnExit( FALSE ),
00116 wroteToStdinConnected( FALSE ),
00117 readStdoutCalled( FALSE ), readStderrCalled( FALSE ),
00118 comms( Stdin|Stdout|Stderr )
00119 {
00120 init();
00121 setArguments( args );
00122 }
00123
00124
00132 QStringList QProcess::arguments() const
00133 {
00134 return _arguments;
00135 }
00136
00142 void QProcess::clearArguments()
00143 {
00144 _arguments.clear();
00145 }
00146
00154 void QProcess::setArguments( const QStringList& args )
00155 {
00156 _arguments = args;
00157 }
00158
00167 void QProcess::addArgument( const QString& arg )
00168 {
00169 _arguments.append( arg );
00170 }
00171
00172 #ifndef QT_NO_DIR
00173
00180 QDir QProcess::workingDirectory() const
00181 {
00182 return workingDir;
00183 }
00184
00194 void QProcess::setWorkingDirectory( const QDir& dir )
00195 {
00196 workingDir = dir;
00197 }
00198 #endif //QT_NO_DIR
00199
00205 int QProcess::communication() const
00206 {
00207 return comms;
00208 }
00209
00219 void QProcess::setCommunication( int commFlags )
00220 {
00221 comms = commFlags;
00222 }
00223
00231 bool QProcess::normalExit() const
00232 {
00233
00234 if ( isRunning() )
00235 return FALSE;
00236 else
00237 return exitNormal;
00238 }
00239
00251 int QProcess::exitStatus() const
00252 {
00253
00254 if ( isRunning() )
00255 return 0;
00256 else
00257 return exitStat;
00258 }
00259
00260
00271 QByteArray QProcess::readStdout()
00272 {
00273 if ( readStdoutCalled ) {
00274 return QByteArray();
00275 }
00276 readStdoutCalled = TRUE;
00277
00278 QByteArray buf = bufStdout()->copy();
00279 consumeBufStdout( -1 );
00280
00281 readStdoutCalled = FALSE;
00282 return buf;
00283 }
00284
00295 QByteArray QProcess::readStderr()
00296 {
00297 if ( readStderrCalled ) {
00298 return QByteArray();
00299 }
00300 readStderrCalled = TRUE;
00301
00302 QByteArray buf = bufStderr()->copy();
00303 consumeBufStderr( -1 );
00304
00305 readStderrCalled = FALSE;
00306 return buf;
00307 }
00308
00315 bool QProcess::canReadLineStdout() const
00316 {
00317 QProcess *that = (QProcess*)this;
00318 return that->scanNewline( TRUE, 0 );
00319 }
00320
00327 bool QProcess::canReadLineStderr() const
00328 {
00329 QProcess *that = (QProcess*)this;
00330 return that->scanNewline( FALSE, 0 );
00331 }
00332
00340 QString QProcess::readLineStdout()
00341 {
00342 QByteArray a;
00343 QString s;
00344 if ( scanNewline( TRUE, &a ) ) {
00345 if ( a.isEmpty() )
00346 s = "";
00347 else
00348 s = QString( a );
00349 }
00350 return s;
00351 }
00352
00360 QString QProcess::readLineStderr()
00361 {
00362 QByteArray a;
00363 QString s;
00364 if ( scanNewline( FALSE, &a ) ) {
00365 if ( a.isEmpty() )
00366 s = "";
00367 else
00368 s = QString( a );
00369 }
00370 return s;
00371 }
00372
00378 bool QProcess::scanNewline( bool stdOut, QByteArray *store )
00379 {
00380 QByteArray *buf;
00381 if ( stdOut )
00382 buf = bufStdout();
00383 else
00384 buf = bufStderr();
00385 uint n = buf->size();
00386 uint i;
00387 for ( i=0; i<n; i++ ) {
00388 if ( buf->at(i) == '\n' ) {
00389 break;
00390 }
00391 }
00392 if ( i >= n )
00393 return FALSE;
00394
00395 if ( store ) {
00396 uint lineLength = i;
00397 if ( lineLength>0 && buf->at(lineLength-1) == '\r' )
00398 lineLength--;
00399 store->resize( lineLength );
00400 memcpy( store->data(), buf->data(), lineLength );
00401 if ( stdOut )
00402 consumeBufStdout( i+1 );
00403 else
00404 consumeBufStderr( i+1 );
00405 }
00406 return TRUE;
00407 }
00408
00459 bool QProcess::launch( const QByteArray& buf, QStringList *env )
00460 {
00461 if ( start( env ) ) {
00462 if ( !buf.isEmpty() ) {
00463 connect( this, SIGNAL(wroteToStdin()),
00464 this, SLOT(closeStdinLaunch()) );
00465 writeToStdin( buf );
00466 } else {
00467 closeStdin();
00468 emit launchFinished();
00469 }
00470 return TRUE;
00471 } else {
00472 emit launchFinished();
00473 return FALSE;
00474 }
00475 }
00476
00482 bool QProcess::launch( const QString& buf, QStringList *env )
00483 {
00484 if ( start( env ) ) {
00485 if ( !buf.isEmpty() ) {
00486 connect( this, SIGNAL(wroteToStdin()),
00487 this, SLOT(closeStdinLaunch()) );
00488 writeToStdin( buf );
00489 } else {
00490 closeStdin();
00491 emit launchFinished();
00492 }
00493 return TRUE;
00494 } else {
00495 emit launchFinished();
00496 return FALSE;
00497 }
00498 }
00499
00503 void QProcess::closeStdinLaunch()
00504 {
00505 disconnect( this, SIGNAL(wroteToStdin()),
00506 this, SLOT(closeStdinLaunch()) );
00507 closeStdin();
00508 emit launchFinished();
00509 }
00510
00511
00563 void QProcess::writeToStdin( const QString& buf )
00564 {
00565 QByteArray tmp = buf.local8Bit();
00566 tmp.resize( buf.length() );
00567 writeToStdin( tmp );
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00581 void QProcess::connectNotify( const char * signal )
00582 {
00583 #if defined(QT_QPROCESS_DEBUG)
00584 odebug << "QProcess::connectNotify(): signal " << signal << " has been connected" << oendl;
00585 #endif
00586 if ( !ioRedirection )
00587 if ( qstrcmp( signal, SIGNAL(readyReadStdout()) )==0 ||
00588 qstrcmp( signal, SIGNAL(readyReadStderr()) )==0
00589 ) {
00590 #if defined(QT_QPROCESS_DEBUG)
00591 odebug << "QProcess::connectNotify(): set ioRedirection to TRUE" << oendl;
00592 #endif
00593 setIoRedirection( TRUE );
00594 return;
00595 }
00596 if ( !notifyOnExit && qstrcmp( signal, SIGNAL(processExited()) )==0 ) {
00597 #if defined(QT_QPROCESS_DEBUG)
00598 odebug << "QProcess::connectNotify(): set notifyOnExit to TRUE" << oendl;
00599 #endif
00600 setNotifyOnExit( TRUE );
00601 return;
00602 }
00603 if ( !wroteToStdinConnected && qstrcmp( signal, SIGNAL(wroteToStdin()) )==0 ) {
00604 #if defined(QT_QPROCESS_DEBUG)
00605 odebug << "QProcess::connectNotify(): set wroteToStdinConnected to TRUE" << oendl;
00606 #endif
00607 setWroteStdinConnected( TRUE );
00608 return;
00609 }
00610 }
00611
00614 void QProcess::disconnectNotify( const char * )
00615 {
00616 if ( ioRedirection &&
00617 receivers( SIGNAL(readyReadStdout()) ) ==0 &&
00618 receivers( SIGNAL(readyReadStderr()) ) ==0
00619 ) {
00620 #if defined(QT_QPROCESS_DEBUG)
00621 odebug << "QProcess::disconnectNotify(): set ioRedirection to FALSE" << oendl;
00622 #endif
00623 setIoRedirection( FALSE );
00624 }
00625 if ( notifyOnExit && receivers( SIGNAL(processExited()) ) == 0 ) {
00626 #if defined(QT_QPROCESS_DEBUG)
00627 odebug << "QProcess::disconnectNotify(): set notifyOnExit to FALSE" << oendl;
00628 #endif
00629 setNotifyOnExit( FALSE );
00630 }
00631 if ( wroteToStdinConnected && receivers( SIGNAL(wroteToStdin()) ) == 0 ) {
00632 #if defined(QT_QPROCESS_DEBUG)
00633 odebug << "QProcess::disconnectNotify(): set wroteToStdinConnected to FALSE" << oendl;
00634 #endif
00635 setWroteStdinConnected( FALSE );
00636 }
00637 }
00638
00639 #endif // QT_NO_PROCESS