#include <q3process.h>
Inheritance diagram for Q3Process:


You can write to the started program's standard input, and can read the program's standard output and standard error. You can pass command line arguments to the program either in the constructor or with setArguments() or addArgument(). The program's working directory can be set with setWorkingDirectory(). If you need to set up environment variables pass them to the start() or launch() functions (see below). The processExited() signal is emitted if the program exits. The program's exit status is available from exitStatus(), although you could simply call normalExit() to see if the program terminated normally.
There are two different ways to start a process. If you just want to run a program, optionally passing data to its standard input at the beginning, use one of the launch() functions. If you want full control of the program's standard input (especially if you don't know all the data you want to send to standard input at the beginning), use the start() function.
If you use start() you can write to the program's standard input using writeToStdin() and you can close the standard input with closeStdin(). The wroteToStdin() signal is emitted if the data sent to standard input has been written. You can read from the program's standard output using readStdout() or readLineStdout(). These functions return an empty QByteArray if there is no data to read. The readyReadStdout() signal is emitted when there is data available to be read from standard output. Standard error has a set of functions that correspond to the standard output functions, i.e. readStderr(), readLineStderr() and readyReadStderr().
If you use one of the launch() functions the data you pass will be sent to the program's standard input which will be closed once all the data has been written. You should not use writeToStdin() or closeStdin() if you use launch(). If you need to send data to the program's standard input after it has started running use start() instead of launch().
Both start() and launch() can accept a string list of strings each of which has the format, key=value, where the keys are the names of environment variables.
You can test to see if a program is running with isRunning(). The program's process identifier is available from processIdentifier(). If you want to terminate a running program use tryTerminate(), but note that the program may ignore this. If you really want to terminate the program, without it having any chance to clean up, you can use kill().
Although you may need quotes for a file named on the command line (e.g. if it contains spaces) you shouldn't use extra quotes for arguments passed to addArgument() or setArguments().
The readyReadStdout() signal is emitted when there is new data on standard output. This happens asynchronously: you don't know if more data will arrive later.
In the above example you could connect the processExited() signal to the slot UicManager::readFromStdout() instead. If you do so, you will be certain that all the data is available when the slot is called. On the other hand, you must wait until the process has finished before doing any processing.
Note that if you are expecting a lot of output from the process, you may hit platform-dependent limits to the pipe buffer size. The solution is to make sure you connect to the output, e.g. the readyReadStdout() and readyReadStderr() signals and read the data as soon as it becomes available.
Please note that Q3Process does not emulate a shell. This means that Q3Process does not do any expansion of arguments: a '*' is passed as a '*' to the program and is not replaced by all the files, a '$HOME' is also passed literally and is not replaced by the environment variable HOME and the special characters for IO redirection ('>', '|', etc.) are also passed literally and do not have the special meaning as they have in a shell.
Also note that Q3Process does not emulate a terminal. This means that certain programs which need direct terminal control, do not work as expected with Q3Process. Such programs include console email programs (like pine and mutt) but also programs which require the user to enter a password (like su and ssh).
Some Windows commands, for example, \c dir, are not provided by separate applications, but by the command interpreter. If you attempt to use Q3Process to execute these commands directly it won't work. One possible solution is to execute the command interpreter itself (\c cmd.exe on some Windows systems), and ask the interpreter to execute the desired command. Under Windows there are certain problems starting 16-bit applications and capturing their output. Microsoft recommends using an intermediate application to start 16-bit applications. \sa Q3Socket Definition at line 40 of file q3process.h.
Public Types | |
| enum | Communication |
| typedef Q_LONG | PID |
Public Slots | |
| void | tryTerminate () const |
| void | kill () const |
| virtual void | writeToStdin (const QByteArray &buf) |
| virtual void | writeToStdin (const QString &buf) |
| virtual void | closeStdin () |
Signals | |
| void | readyReadStdout () |
| void | readyReadStderr () |
| void | processExited () |
| void | wroteToStdin () |
| void | launchFinished () |
Public Member Functions | |
| Q3Process (QObject *parent=0, const char *name=0) | |
| Q3Process (const QString &arg0, QObject *parent=0, const char *name=0) | |
| Q3Process (const QStringList &args, QObject *parent=0, const char *name=0) | |
| ~Q3Process () | |
| QStringList | arguments () const |
| void | clearArguments () |
| virtual void | setArguments (const QStringList &args) |
| virtual void | addArgument (const QString &arg) |
| QDir | workingDirectory () const |
| virtual void | setWorkingDirectory (const QDir &dir) |
| void | setCommunication (int c) |
| int | communication () const |
| virtual bool | start (QStringList *env=0) |
| virtual bool | launch (const QString &buf, QStringList *env=0) |
| virtual bool | launch (const QByteArray &buf, QStringList *env=0) |
| bool | isRunning () const |
| bool | normalExit () const |
| int | exitStatus () const |
| virtual QByteArray | readStdout () |
| virtual QByteArray | readStderr () |
| bool | canReadLineStdout () const |
| bool | canReadLineStderr () const |
| virtual QString | readLineStdout () |
| virtual QString | readLineStderr () |
| PID | processIdentifier () |
| void | flushStdin () |
Protected Member Functions | |
| void | connectNotify (const char *signal) |
| void | disconnectNotify (const char *signal) |
Private Slots | |
| void | socketRead (int fd) |
| void | socketWrite (int fd) |
| void | timeout () |
| void | closeStdinLaunch () |
Private Member Functions | |
| void | setIoRedirection (bool value) |
| void | setNotifyOnExit (bool value) |
| void | setWroteStdinConnected (bool value) |
| void | init () |
| void | reset () |
| Q3Membuf * | membufStdout () |
| Q3Membuf * | membufStderr () |
Private Attributes | |
| Q3ProcessPrivate * | d |
| QDir | workingDir |
| QStringList | _arguments |
| int | exitStat |
| bool | exitNormal |
| bool | ioRedirection |
| bool | notifyOnExit |
| bool | wroteToStdinConnected |
| bool | readStdoutCalled |
| bool | readStderrCalled |
| int | comms |
Friends | |
| class | Q3ProcessPrivate |
Definition at line 86 of file q3process.h.
This enum type defines the communication channels connected to the process.
Stdin Data can be written to the process's standard input.
Stdout Data can be read from the process's standard output.
Stderr Data can be read from the process's standard error.
DupStderr Both the process's standard error output and its standard output are written to its standard output. (Like Unix's dup2().) This means that nothing is sent to the standard error output. This is especially useful if your application requires that the output on standard output and on standard error must be read in the same order that they are produced. This is a flag, so to activate it you must pass {Stdout|Stderr|DupStderr}, or {Stdin|Stdout|Stderr|DupStderr} if you want to provide input, to the setCommunication() call.
Definition at line 60 of file q3process.h.
| Q3Process::Q3Process | ( | QObject * | parent = 0, |
|
| const char * | name = 0 | |||
| ) |
Constructs a Q3Process object. The parent and name parameters are passed to the QObject constructor.
Definition at line 175 of file q3process.cpp.
References init().
00176 : QObject( parent, name ), ioRedirection( false ), notifyOnExit( false ), 00177 wroteToStdinConnected( false ), 00178 readStdoutCalled( false ), readStderrCalled( false ), 00179 comms( Stdin|Stdout|Stderr ) 00180 { 00181 init(); 00182 }
Here is the call graph for this function:

Constructs a Q3Process with arg0 as the command to be executed. The parent and name parameters are passed to the QObject constructor.
The process is not started. You must call start() or launch() to start the process.
Definition at line 194 of file q3process.cpp.
References addArgument(), and init().
00195 : QObject( parent, name ), ioRedirection( false ), notifyOnExit( false ), 00196 wroteToStdinConnected( false ), 00197 readStdoutCalled( false ), readStderrCalled( false ), 00198 comms( Stdin|Stdout|Stderr ) 00199 { 00200 init(); 00201 addArgument( arg0 ); 00202 }
Here is the call graph for this function:

| Q3Process::Q3Process | ( | const QStringList & | args, | |
| QObject * | parent = 0, |
|||
| const char * | name = 0 | |||
| ) |
Constructs a Q3Process with args as the arguments of the process. The first element in the list is the command to be executed. The other elements in the list are the arguments to this command. The parent and name parameters are passed to the QObject constructor.
The process is not started. You must call start() or launch() to start the process.
Definition at line 216 of file q3process.cpp.
References init(), and setArguments().
00217 : QObject( parent, name ), ioRedirection( false ), notifyOnExit( false ), 00218 wroteToStdinConnected( false ), 00219 readStdoutCalled( false ), readStderrCalled( false ), 00220 comms( Stdin|Stdout|Stderr ) 00221 { 00222 init(); 00223 setArguments( args ); 00224 }
Here is the call graph for this function:

| Q3Process::~Q3Process | ( | ) |
Destroys the instance.
If the process is running, it is not terminated! The standard input, standard output and standard error of the process are closed.
You can connect the destroyed() signal to the kill() slot, if you want the process to be terminated automatically when the instance is destroyed.
Definition at line 645 of file q3process_unix.cpp.
References d.
00646 { 00647 delete d; 00648 }
| QStringList Q3Process::arguments | ( | ) | const |
Returns the list of arguments that are set for the process. Arguments can be specified with the constructor or with the functions setArguments() and addArgument().
Note that if you want to iterate over the list, you should iterate over a copy, e.g.
QStringList list = myProcess.arguments(); QStringList::Iterator it = list.begin(); while( it != list.end() ) { myProcessing( *it ); ++it; }
Definition at line 245 of file q3process.cpp.
References _arguments.
00246 { 00247 return _arguments; 00248 }
| void Q3Process::clearArguments | ( | ) |
Clears the list of arguments that are set for the process.
Definition at line 255 of file q3process.cpp.
References _arguments, and QList< T >::clear().
00256 { 00257 _arguments.clear(); 00258 }
Here is the call graph for this function:

| void Q3Process::setArguments | ( | const QStringList & | args | ) | [virtual] |
Sets args as the arguments for the process. The first element in the list is the command to be executed. The other elements in the list are the arguments to the command. Any previous arguments are deleted.
Q3Process does not perform argument substitutions; for example, if you specify "*" or "$DISPLAY", these values are passed to the process literally. If you want to have the same behavior as the shell provides, you must do the substitutions yourself; i.e. instead of specifying a "*" you must specify the list of all the filenames in the current directory, and instead of "$DISPLAY" you must specify the value of the environment variable DISPLAY.
Note for Windows users. The standard Windows shells, e.g. command.com and cmd.exe, do not perform file globbing, i.e. they do not convert a "*" on the command line into a list of files in the current directory. For this reason most Windows applications implement their own file globbing, and as a result of this, specifying an argument of "*" for a Windows application is likely to result in the application performing a file glob and ending up with a list of filenames.
Definition at line 285 of file q3process.cpp.
References _arguments.
Referenced by Q3Process().
00286 { 00287 _arguments = args; 00288 }
| void Q3Process::addArgument | ( | const QString & | arg | ) | [virtual] |
Adds arg to the end of the list of arguments.
The first element in the list of arguments is the command to be executed; the following elements are the command's arguments.
Definition at line 298 of file q3process.cpp.
References _arguments, and QList< T >::append().
Referenced by Q3Process().
00299 { 00300 _arguments.append( arg ); 00301 }
Here is the call graph for this function:

| QDir Q3Process::workingDirectory | ( | ) | const |
Returns the working directory that was set with setWorkingDirectory(), or the current directory if none has been explicitly set.
Definition at line 311 of file q3process.cpp.
References workingDir.
00312 { 00313 return workingDir; 00314 }
| void Q3Process::setWorkingDirectory | ( | const QDir & | dir | ) | [virtual] |
Sets dir as the working directory for processes. This does not affect running processes; only processes that are started afterwards are affected.
Setting the working directory is especially useful for processes that try to access files with relative paths.
Definition at line 326 of file q3process.cpp.
References workingDir.
00327 { 00328 workingDir = dir; 00329 }
| void Q3Process::setCommunication | ( | int | commFlags | ) |
Sets commFlags as the communication required with the process.
commFlags is a bitwise OR of the flags defined by the Communication enum.
The default is {Stdin|Stdout|Stderr}.
Definition at line 353 of file q3process.cpp.
References comms.
00354 { 00355 comms = commFlags; 00356 }
| int Q3Process::communication | ( | ) | const |
Returns the communication required with the process, i.e. some combination of the Communication flags.
Definition at line 338 of file q3process.cpp.
References comms.
00339 { 00340 return comms; 00341 }
| bool Q3Process::start | ( | QStringList * | env = 0 |
) | [virtual] |
Tries to run a process for the command and arguments that were specified with setArguments(), addArgument() or that were specified in the constructor. The command is searched for in the path for executable programs; you can also use an absolute path in the command itself.
If env is null, then the process is started with the same environment as the starting process. If env is non-null, then the values in the stringlist are interpreted as environment setttings of the form {key=value} and the process is started in these environment settings. For convenience, there is a small exception to this rule: under Unix, if env does not contain any settings for the environment variable LD_LIBRARY_PATH, then this variable is inherited from the starting process; under Windows the same applies for the environment variable PATH.
Returns true if the process could be started; otherwise returns false.
You can write data to the process's standard input with writeToStdin(). You can close standard input with closeStdin() and you can terminate the process with tryTerminate(), or with kill().
You can call this function even if you've used this instance to create a another process which is still running. In such cases, Q3Process closes the old process's standard input and deletes pending data, i.e., you lose all control over the old process, but the old process is not terminated. This applies also if the process could not be started. (On operating systems that have zombie processes, Qt will also wait() on the old process.)
Definition at line 684 of file q3process_unix.cpp.
References _arguments, QList< T >::begin(), buf, Q3ProcessManager::cleanup(), Q3ProcessPrivate::closeOpenSocketsForChild(), comms, QObject::connect(), QList< T >::count(), d, DupStderr, QList< T >::empty(), QList< T >::end(), error, QFile::exists(), QFileInfo::exists(), QFileInfo::filePath(), i, ioRedirection, QFileInfo::isDir(), Q3PtrQueue< type >::isEmpty(), QFileInfo::isExecutable(), Q3CString::mid(), n, Q3ProcessPrivate::newProc(), Q3ProcessPrivate::notifierStderr, Q3ProcessPrivate::notifierStdin, Q3ProcessPrivate::notifierStdout, Q3ProcessPrivate::proc, Q3ProcessPrivate::procManager, q3process_cleanup(), qAddPostRoutine(), qDebug(), QSocketNotifier::Read, reset(), Q3CString::right(), QSocketNotifier::setEnabled(), SIGNAL, SLOT, socketRead(), QProc::socketStderr, QProc::socketStdin, QProc::socketStdout, socketWrite(), Stderr, Stdin, Q3ProcessPrivate::stdinBuf, Stdout, workingDir, and QSocketNotifier::Write.
Referenced by launch().
00685 { 00686 #if defined(QT_Q3PROCESS_DEBUG) 00687 qDebug( "Q3Process::start()" ); 00688 #endif 00689 reset(); 00690 00691 int sStdin[2]; 00692 int sStdout[2]; 00693 int sStderr[2]; 00694 00695 // open sockets for piping 00696 #ifndef Q_OS_QNX6 00697 if ( (comms & Stdin) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdin ) == -1 ) { 00698 #else 00699 if ( (comms & Stdin) && qnx6SocketPairReplacement(sStdin) == -1 ) { 00700 #endif 00701 return false; 00702 } 00703 #ifndef Q_OS_QNX6 00704 if ( (comms & Stderr) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStderr ) == -1 ) { 00705 #else 00706 if ( (comms & Stderr) && qnx6SocketPairReplacement(sStderr) == -1 ) { 00707 #endif 00708 if ( comms & Stdin ) { 00709 ::close( sStdin[0] ); 00710 ::close( sStdin[1] ); 00711 } 00712 return false; 00713 } 00714 #ifndef Q_OS_QNX6 00715 if ( (comms & Stdout) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdout ) == -1 ) { 00716 #else 00717 if ( (comms & Stdout) && qnx6SocketPairReplacement(sStdout) == -1 ) { 00718 #endif 00719 if ( comms & Stdin ) { 00720 ::close( sStdin[0] ); 00721 ::close( sStdin[1] ); 00722 } 00723 if ( comms & Stderr ) { 00724 ::close( sStderr[0] ); 00725 ::close( sStderr[1] ); 00726 } 00727 return false; 00728 } 00729 00730 // the following pipe is only used to determine if the process could be 00731 // started 00732 int fd[2]; 00733 if ( pipe( fd ) < 0 ) { 00734 // non critical error, go on 00735 fd[0] = 0; 00736 fd[1] = 0; 00737 } 00738 00739 // construct the arguments for exec 00740 Q3CString *arglistQ = new Q3CString[ _arguments.count() + 1 ]; 00741 const char** arglist = new const char*[ _arguments.count() + 1 ]; 00742 int i = 0; 00743 for ( QStringList::Iterator it = _arguments.begin(); it != _arguments.end(); ++it ) { 00744 arglistQ[i] = (*it).local8Bit(); 00745 arglist[i] = arglistQ[i]; 00746 #if defined(QT_Q3PROCESS_DEBUG) 00747 qDebug( "Q3Process::start(): arg %d = %s", i, arglist[i] ); 00748 #endif 00749 i++; 00750 } 00751 #ifdef Q_OS_MACX 00752 if(i) { 00753 Q3CString arg_bundle = arglistQ[0]; 00754 QFileInfo fi(arg_bundle); 00755 if(fi.exists() && fi.isDir() && arg_bundle.right(4) == ".app") { 00756 Q3CString exe = arg_bundle; 00757 int lslash = exe.findRev('/'); 00758 if(lslash != -1) 00759 exe = exe.mid(lslash+1); 00760 exe = Q3CString(arg_bundle + "/Contents/MacOS/" + exe); 00761 exe = exe.left(exe.length() - 4); //chop off the .app 00762 if(QFile::exists(exe)) { 00763 arglistQ[0] = exe; 00764 arglist[0] = arglistQ[0]; 00765 } 00766 } 00767 } 00768 #endif 00769 arglist[i] = 0; 00770 00771 // Must make sure signal handlers are installed before exec'ing 00772 // in case the process exits quickly. 00773 if ( d->procManager == 0 ) { 00774 d->procManager = new Q3ProcessManager; 00775 qAddPostRoutine(q3process_cleanup); 00776 } 00777 00778 // fork and exec 00779 QApplication::flushX(); 00780 pid_t pid = fork(); 00781 if ( pid == 0 ) { 00782 // child 00783 d->closeOpenSocketsForChild(); 00784 if ( comms & Stdin ) { 00785 ::close( sStdin[1] ); 00786 ::dup2( sStdin[0], STDIN_FILENO ); 00787 } 00788 if ( comms & Stdout ) { 00789 ::close( sStdout[0] ); 00790 ::dup2( sStdout[1], STDOUT_FILENO ); 00791 } 00792 if ( comms & Stderr ) { 00793 ::close( sStderr[0] ); 00794 ::dup2( sStderr[1], STDERR_FILENO ); 00795 } 00796 if ( comms & DupStderr ) { 00797 ::dup2( STDOUT_FILENO, STDERR_FILENO ); 00798 } 00799 #ifndef QT_NO_DIR 00800 ::chdir( workingDir.absPath().latin1() ); 00801 #endif 00802 if ( fd[0] ) 00803 ::close( fd[0] ); 00804 if ( fd[1] ) 00805 ::fcntl( fd[1], F_SETFD, FD_CLOEXEC ); // close on exec shows success 00806 00807 if ( env == 0 ) { // inherit environment and start process 00808 #ifndef Q_OS_QNX4 00809 ::execvp( arglist[0], (char*const*)arglist ); // ### cast not nice 00810 #else 00811 ::execvp( arglist[0], (char const*const*)arglist ); // ### cast not nice 00812 #endif 00813 } else { // start process with environment settins as specified in env 00814 // construct the environment for exec 00815 int numEntries = env->count(); 00816 #if defined(Q_OS_MACX) 00817 QString ld_library_path("DYLD_LIBRARY_PATH"); 00818 #else 00819 QString ld_library_path("LD_LIBRARY_PATH"); 00820 #endif 00821 bool setLibraryPath = 00822 env->grep( QRegExp( "^" + ld_library_path + "=" ) ).empty() && 00823 getenv( ld_library_path.local8Bit() ) != 0; 00824 if ( setLibraryPath ) 00825 numEntries++; 00826 Q3CString *envlistQ = new Q3CString[ numEntries + 1 ]; 00827 const char** envlist = new const char*[ numEntries + 1 ]; 00828 int i = 0; 00829 if ( setLibraryPath ) { 00830 envlistQ[i] = QString( ld_library_path + "=%1" ).arg( getenv( ld_library_path.local8Bit() ) ).local8Bit(); 00831 envlist[i] = envlistQ[i]; 00832 i++; 00833 } 00834 for ( QStringList::Iterator it = env->begin(); it != env->end(); ++it ) { 00835 envlistQ[i] = (*it).local8Bit(); 00836 envlist[i] = envlistQ[i]; 00837 i++; 00838 } 00839 envlist[i] = 0; 00840 00841 // look for the executable in the search path 00842 if ( _arguments.count()>0 && getenv("PATH")!=0 ) { 00843 QString command = _arguments[0]; 00844 if ( !command.contains( '/' ) ) { 00845 QStringList pathList = QStringList::split( ':', getenv( "PATH" ) ); 00846 for (QStringList::Iterator it = pathList.begin(); it != pathList.end(); ++it ) { 00847 QString dir = *it; 00848 #if defined(Q_OS_MACX) //look in a bundle 00849 if(!QFile::exists(dir + "/" + command) && QFile::exists(dir + "/" + command + ".app")) 00850 dir += "/" + command + ".app/Contents/MacOS"; 00851 #endif 00852 #ifndef QT_NO_DIR 00853 QFileInfo fileInfo( dir, command ); 00854 #else 00855 QFileInfo fileInfo( dir + "/" + command ); 00856 #endif 00857 if ( fileInfo.isExecutable() ) { 00858 #if defined(Q_OS_MACX) 00859 arglistQ[0] = fileInfo.absFilePath().local8Bit(); 00860 #else 00861 arglistQ[0] = fileInfo.filePath().local8Bit(); 00862 #endif 00863 arglist[0] = arglistQ[0]; 00864 break; 00865 } 00866 } 00867 } 00868 } 00869 #ifndef Q_OS_QNX4 00870 ::execve( arglist[0], (char*const*)arglist, (char*const*)envlist ); // ### casts not nice 00871 #else 00872 ::execve( arglist[0], (char const*const*)arglist,(char const*const*)envlist ); // ### casts not nice 00873 #endif 00874 } 00875 if ( fd[1] ) { 00876 char buf = 0; 00877 ::write( fd[1], &buf, 1 ); 00878 ::close( fd[1] ); 00879 } 00880 ::_exit( -1 ); 00881 } else if ( pid == -1 ) { 00882 // error forking 00883 goto error; 00884 } 00885 00886 // test if exec was successful 00887 if ( fd[1] ) 00888 ::close( fd[1] ); 00889 if ( fd[0] ) { 00890 char buf; 00891 for ( ;; ) { 00892 int n = ::read( fd[0], &buf, 1 ); 00893 if ( n==1 ) { 00894 // socket was not closed => error 00895 if ( ::waitpid( pid, 0, WNOHANG ) != pid ) { 00896 // The wait did not succeed yet, so try again when we get 00897 // the sigchild (to avoid zombies). 00898 d->newProc( pid, 0 ); 00899 } 00900 d->proc = 0; 00901 goto error; 00902 } else if ( n==-1 ) { 00903 if ( errno==EAGAIN || errno==EINTR ) 00904 // try it again 00905 continue; 00906 } 00907 break; 00908 } 00909 ::close( fd[0] ); 00910 } 00911 00912 d->newProc( pid, this ); 00913 00914 if ( comms & Stdin ) { 00915 ::close( sStdin[0] ); 00916 d->proc->socketStdin = sStdin[1]; 00917 00918 // Select non-blocking mode 00919 int originalFlags = fcntl(d->proc->socketStdin, F_GETFL, 0); 00920 fcntl(d->proc->socketStdin, F_SETFL, originalFlags | O_NONBLOCK); 00921 00922 d->notifierStdin = new QSocketNotifier( sStdin[1], QSocketNotifier::Write ); 00923 connect( d->notifierStdin, SIGNAL(activated(int)), 00924 this, SLOT(socketWrite(int)) ); 00925 // setup notifiers for the sockets 00926 if ( !d->stdinBuf.isEmpty() ) { 00927 d->notifierStdin->setEnabled( true ); 00928 } 00929 } 00930 if ( comms & Stdout ) { 00931 ::close( sStdout[1] ); 00932 d->proc->socketStdout = sStdout[0]; 00933 d->notifierStdout = new QSocketNotifier( sStdout[0], QSocketNotifier::Read ); 00934 connect( d->notifierStdout, SIGNAL(activated(int)), 00935 this, SLOT(socketRead(int)) ); 00936 if ( ioRedirection ) 00937 d->notifierStdout->setEnabled( true ); 00938 } 00939 if ( comms & Stderr ) { 00940 ::close( sStderr[1] ); 00941 d->proc->socketStderr = sStderr[0]; 00942 d->notifierStderr = new QSocketNotifier( sStderr[0], QSocketNotifier::Read ); 00943 connect( d->notifierStderr, SIGNAL(activated(int)), 00944 this, SLOT(socketRead(int)) ); 00945 if ( ioRedirection ) 00946 d->notifierStderr->setEnabled( true ); 00947 } 00948 00949 // cleanup and return 00950 delete[] arglistQ; 00951 delete[] arglist; 00952 return true; 00953 00954 error: 00955 #if defined(QT_Q3PROCESS_DEBUG) 00956 qDebug( "Q3Process::start(): error starting process" ); 00957 #endif 00958 if ( d->procManager ) 00959 d->procManager->cleanup(); 00960 if ( comms & Stdin ) { 00961 ::close( sStdin[1] ); 00962 ::close( sStdin[0] ); 00963 } 00964 if ( comms & Stdout ) { 00965 ::close( sStdout[0] ); 00966 ::close( sStdout[1] ); 00967 } 00968 if ( comms & Stderr ) { 00969 ::close( sStderr[0] ); 00970 ::close( sStderr[1] ); 00971 } 00972 ::close( fd[0] ); 00973 ::close( fd[1] ); 00974 delete[] arglistQ; 00975 delete[] arglist; 00976 return false; 00977 }
Here is the call graph for this function:

| bool Q3Process::launch | ( | const QString & | buf, | |
| QStringList * | env = 0 | |||
| ) | [virtual] |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. The data buf is written to standard input with writeToStdin() using the QString::local8Bit() representation of the strings.
Definition at line 592 of file q3process.cpp.
References buf, closeStdin(), closeStdinLaunch(), QObject::connect(), emit, launchFinished(), SIGNAL, SLOT, start(), writeToStdin(), and wroteToStdin().
00593 { 00594 if ( start( env ) ) { 00595 if ( !buf.isEmpty() ) { 00596 connect( this, SIGNAL(wroteToStdin()), 00597 this, SLOT(closeStdinLaunch()) ); 00598 writeToStdin( buf ); 00599 } else { 00600 closeStdin(); 00601 emit launchFinished(); 00602 } 00603 return true; 00604 } else { 00605 emit launchFinished(); 00606 return false; 00607 } 00608 }
Here is the call graph for this function:

| bool Q3Process::launch | ( | const QByteArray & | buf, | |
| QStringList * | env = 0 | |||
| ) | [virtual] |
Runs the process and writes the data buf to the process's standard input. If all the data is written to standard input, standard input is closed. The command is searched for in the path for executable programs; you can also use an absolute path in the command itself.
If env is null, then the process is started with the same environment as the starting process. If env is non-null, then the values in the string list are interpreted as environment setttings of the form {key=value} and the process is started with these environment settings. For convenience, there is a small exception to this rule under Unix: if env does not contain any settings for the environment variable LD_LIBRARY_PATH, then this variable is inherited from the starting process.
Returns true if the process could be started; otherwise returns false.
Note that you should not use the slots writeToStdin() and closeStdin() on processes started with launch(), since the result is not well-defined. If you need these slots, use start() instead.
The process may or may not read the buf data sent to its standard input.
You can call this function even when a process that was started with this instance is still running. Be aware that if you do this the standard input of the process that was launched first will be closed, with any pending data being deleted, and the process will be left to run out of your control. Similarly, if the process could not be started the standard input will be closed and the pending data deleted. (On operating systems that have zombie processes, Qt will also wait() on the old process.)
The object emits the signal launchFinished() when this function call is finished. If the start was successful, this signal is emitted after all the data has been written to standard input. If the start failed, then this signal is emitted immediately.
Definition at line 568 of file q3process.cpp.
References buf, closeStdin(), closeStdinLaunch(), QObject::connect(), emit, launchFinished(), SIGNAL, SLOT, start(), writeToStdin(), and wroteToStdin().
00569 { 00570 if ( start( env ) ) { 00571 if ( !buf.isEmpty() ) { 00572 connect( this, SIGNAL(wroteToStdin()), 00573 this, SLOT(closeStdinLaunch()) ); 00574 writeToStdin( buf ); 00575 } else { 00576 closeStdin(); 00577 emit launchFinished(); 00578 } 00579 return true; 00580 } else { 00581 emit launchFinished(); 00582 return false; 00583 } 00584 }
Here is the call graph for this function:

| bool Q3Process::isRunning | ( | ) | const |
Returns true if the process is running; otherwise returns false.
Definition at line 1033 of file q3process_unix.cpp.
References d, exitNormal, exitStat, Q3ProcessPrivate::exitValuesCalculated, QProc::pid, Q3ProcessPrivate::proc, Q3ProcessPrivate::procManager, qDebug(), Q3ProcessManager::sigchldFd, and Q3ProcessManager::sigchldHnd().
Referenced by exitStatus(), normalExit(), and Q3ProcessManager::sigchldHnd().
01034 { 01035 if ( d->exitValuesCalculated ) { 01036 #if defined(QT_Q3PROCESS_DEBUG) 01037 qDebug( "Q3Process::isRunning(): false (already computed)" ); 01038 #endif 01039 return false; 01040 } 01041 if ( d->proc == 0 ) 01042 return false; 01043 int status; 01044 if ( ::waitpid( d->proc->pid, &status, WNOHANG ) == d->proc->pid ) { 01045 // compute the exit values 01046 Q3Process *that = (Q3Process*)this; // mutable 01047 that->exitNormal = WIFEXITED( status ) != 0; 01048 if ( exitNormal ) { 01049 that->exitStat = (char)WEXITSTATUS( status ); 01050 } 01051 d->exitValuesCalculated = true; 01052 01053 // On heavy processing, the socket notifier for the sigchild might not 01054 // have found time to fire yet. 01055 if ( d->procManager && d->procManager->sigchldFd[1] < FD_SETSIZE ) { 01056 fd_set fds; 01057 struct timeval tv; 01058 FD_ZERO( &fds ); 01059 FD_SET( d->procManager->sigchldFd[1], &fds ); 01060 tv.tv_sec = 0; 01061 tv.tv_usec = 0; 01062 if ( ::select( d->procManager->sigchldFd[1]+1, &fds, 0, 0, &tv ) > 0 ) 01063 d->procManager->sigchldHnd( d->procManager->sigchldFd[1] ); 01064 } 01065 01066 #if defined(QT_Q3PROCESS_DEBUG) 01067 qDebug( "Q3Process::isRunning() (PID: %d): false", d->proc->pid ); 01068 #endif 01069 return false; 01070 } 01071 #if defined(QT_Q3PROCESS_DEBUG) 01072 qDebug( "Q3Process::isRunning() (PID: %d): true", d->proc->pid ); 01073 #endif 01074 return true; 01075 }
Here is the call graph for this function:

| bool Q3Process::normalExit | ( | ) | const |
Returns true if the process has exited normally; otherwise returns false. This implies that this function returns false if the process is still running.
Definition at line 365 of file q3process.cpp.
References exitNormal, and isRunning().
00366 { 00367 // isRunning() has the side effect that it determines the exit status! 00368 if ( isRunning() ) 00369 return false; 00370 else 00371 return exitNormal; 00372 }
Here is the call graph for this function:

| int Q3Process::exitStatus | ( | ) | const |
Returns the exit status of the process or 0 if the process is still running. This function returns immediately and does not wait until the process is finished.
If normalExit() is false (e.g. if the program was killed or crashed), this function returns 0, so you should check the return value of normalExit() before relying on this value.
Definition at line 385 of file q3process.cpp.
References exitStat, and isRunning().
00386 { 00387 // isRunning() has the side effect that it determines the exit status! 00388 if ( isRunning() ) 00389 return 0; 00390 else 00391 return exitStat; 00392 }
Here is the call graph for this function:

| QByteArray Q3Process::readStdout | ( | ) | [virtual] |
Reads the data that the process has written to standard output. When new data is written to standard output, the class emits the signal readyReadStdout().
If there is no data to read, this function returns a QByteArray of size 0: it does not wait until there is something to read.
Definition at line 405 of file q3process.cpp.
References buf, membufStdout(), and readStdoutCalled.
00406 { 00407 if ( readStdoutCalled ) { 00408 return QByteArray(); 00409 } 00410 readStdoutCalled = true; 00411 Q3Membuf *buf = membufStdout(); 00412 readStdoutCalled = false; 00413 00414 return buf->readAll(); 00415 }
Here is the call graph for this function:

| QByteArray Q3Process::readStderr | ( | ) | [virtual] |
Reads the data that the process has written to standard error. When new data is written to standard error, the class emits the signal readyReadStderr().
If there is no data to read, this function returns a QByteArray of size 0: it does not wait until there is something to read.
Definition at line 427 of file q3process.cpp.
References buf, membufStderr(), and readStderrCalled.
00428 { 00429 if ( readStderrCalled ) { 00430 return QByteArray(); 00431 } 00432 readStderrCalled = true; 00433 Q3Membuf *buf = membufStderr(); 00434 readStderrCalled = false; 00435 00436 return buf->readAll(); 00437 }
Here is the call graph for this function:

| bool Q3Process::canReadLineStdout | ( | ) | const |
Returns true if it's possible to read an entire line of text from standard output at this time; otherwise returns false.
Definition at line 1083 of file q3process_unix.cpp.
References Q3ProcessPrivate::bufStdout, d, membufStdout(), Q3ProcessPrivate::proc, Q3Membuf::scanNewline(), Q3Membuf::size(), and QProc::socketStdout.
Referenced by readLineStdout().
01084 { 01085 if ( !d->proc || !d->proc->socketStdout ) 01086 return d->bufStdout.size() != 0; 01087 01088 Q3Process *that = (Q3Process*)this; 01089 return that->membufStdout()->scanNewline( 0 ); 01090 }
Here is the call graph for this function:

| bool Q3Process::canReadLineStderr | ( | ) | const |
Returns true if it's possible to read an entire line of text from standard error at this time; otherwise returns false.
Definition at line 1098 of file q3process_unix.cpp.
References Q3ProcessPrivate::bufStderr, d, membufStderr(), Q3ProcessPrivate::proc, Q3Membuf::scanNewline(), Q3Membuf::size(), and QProc::socketStderr.
Referenced by readLineStderr().
01099 { 01100 if ( !d->proc || !d->proc->socketStderr ) 01101 return d->bufStderr.size() != 0; 01102 01103 Q3Process *that = (Q3Process*)this; 01104 return that->membufStderr()->scanNewline( 0 ); 01105 }
Here is the call graph for this function:

| QString Q3Process::readLineStdout | ( | ) | [virtual] |
Reads a line of text from standard output, excluding any trailing newline or carriage return characters, and returns it. Returns an empty string if canReadLineStdout() returns false.
By default, the text is interpreted to be in Latin-1 encoding. If you need other codecs, you can set a different codec with QTextCodec::setCodecForCStrings().
Definition at line 450 of file q3process.cpp.
References a, buf, canReadLineStdout(), membufStdout(), and size.
00451 { 00452 QByteArray a( 256 ); 00453 Q3Membuf *buf = membufStdout(); 00454 if ( !buf->scanNewline( &a ) ) { 00455 if ( !canReadLineStdout() ) 00456 return QString(); 00457 00458 if ( !buf->scanNewline( &a ) ) 00459 return QString( buf->readAll() ); 00460 } 00461 00462 uint size = a.size(); 00463 buf->consumeBytes( size, 0 ); 00464 00465 // get rid of terminating \n or \r\n 00466 if ( size>0 && a.at( size - 1 ) == '\n' ) { 00467 if ( size>1 && a.at( size - 2 ) == '\r' ) 00468 a.chop(2); 00469 else 00470 a.chop(1); 00471 } 00472 return QString( a ); 00473 }
Here is the call graph for this function:

| QString Q3Process::readLineStderr | ( | ) | [virtual] |
Reads a line of text from standard error, excluding any trailing newline or carriage return characters and returns it. Returns an empty string if canReadLineStderr() returns false.
By default, the text is interpreted to be in Latin-1 encoding. If you need other codecs, you can set a different codec with QTextCodec::setCodecForCStrings().
Definition at line 486 of file q3process.cpp.
References a, buf, canReadLineStderr(), membufStderr(), and size.
00487 { 00488 QByteArray a( 256 ); 00489 Q3Membuf *buf = membufStderr(); 00490 if ( !buf->scanNewline( &a ) ) { 00491 if ( !canReadLineStderr() ) 00492 return QString(); 00493 00494 if ( !buf->scanNewline( &a ) ) 00495 return QString( buf->readAll() ); 00496 } 00497 00498 uint size = a.size(); 00499 buf->consumeBytes( size, 0 ); 00500 00501 // get rid of terminating \n or \r\n 00502 if ( size>0 && a.at( size - 1 ) == '\n' ) { 00503 if ( size>1 && a.at( size - 2 ) == '\r' ) 00504 a.chop(2); 00505 else 00506 a.chop(1); 00507 } 00508 return QString( a ); 00509 }
Here is the call graph for this function:

| Q3Process::PID Q3Process::processIdentifier | ( | ) |
Returns platform dependent information about the process. This can be used together with platform specific system calls.
Under Unix the return value is the PID of the process, or -1 if no process belongs to this object.
Under Windows it is a pointer to the PROCESS_INFORMATION struct, or 0 if no process is belongs to this object.
Use of this function's return value is likely to be non-portable.
Definition at line 1382 of file q3process_unix.cpp.
References d, QProc::pid, and Q3ProcessPrivate::proc.
| void Q3Process::flushStdin | ( | ) |
Definition at line 1311 of file q3process_unix.cpp.
References d, Q3ProcessPrivate::proc, QProc::socketStdin, and socketWrite().
01312 { 01313 if (d->proc) 01314 socketWrite(d->proc->socketStdin); 01315 }
| void Q3Process::readyReadStdout | ( | ) | [signal] |
This signal is emitted when the process has written data to standard output. You can read the data with readStdout().
Note that this signal is only emitted when there is new data and not when there is old, but unread data. In the slot connected to this signal, you should always read everything that is available at that moment to make sure that you don't lose any data.
Referenced by connectNotify(), disconnectNotify(), and socketRead().
| void Q3Process::readyReadStderr | ( | ) | [signal] |
This signal is emitted when the process has written data to standard error. You can read the data with readStderr().
Note that this signal is only emitted when there is new data and not when there is old, but unread data. In the slot connected to this signal, you should always read everything that is available at that moment to make sure that you don't lose any data.
Referenced by connectNotify(), disconnectNotify(), and socketRead().
| void Q3Process::processExited | ( | ) | [signal] |
This signal is emitted when the process has exited.
Referenced by connectNotify(), disconnectNotify(), and Q3ProcessManager::sigchldHnd().
| void Q3Process::wroteToStdin | ( | ) | [signal] |
This signal is emitted if the data sent to standard input (via writeToStdin()) was actually written to the process. This does not imply that the process really read the data, since this class only detects when it was able to write the data to the operating system. But it is now safe to close standard input without losing pending data.
Referenced by closeStdinLaunch(), connectNotify(), disconnectNotify(), launch(), and socketWrite().
| void Q3Process::launchFinished | ( | ) | [signal] |
This signal is emitted when the process was started with launch(). If the start was successful, this signal is emitted after all the data has been written to standard input. If the start failed, then this signal is emitted immediately.
This signal is especially useful if you want to know when you can safely delete the Q3Process object when you are not interested in reading from standard output or standard error.
Referenced by closeStdinLaunch(), and launch().
| void Q3Process::tryTerminate | ( | ) | const [slot] |
Asks the process to terminate. Processes can ignore this if they wish. If you want to be certain that the process really terminates, you can use kill() instead.
The slot returns immediately: it does not wait until the process has finished. When the process terminates, the processExited() signal is emitted.
Definition at line 991 of file q3process_unix.cpp.
References d, kill(), QProc::pid, and Q3ProcessPrivate::proc.
| void Q3Process::kill | ( | ) | const [slot] |
Terminates the process. This is not a safe way to end a process since the process will not be able to do any cleanup. tryTerminate() is safer, but processes can ignore a tryTerminate().
The nice way to end a process and to be sure that it is finished, is to do something like this:
process->tryTerminate(); QTimer::singleShot( 5000, process, SLOT(kill()) );
This tries to terminate the process the nice way. If the process is still running after 5 seconds, it terminates the process the hard way. The timeout should be chosen depending on the time the process needs to do all its cleanup: use a higher value if the process is likely to do a lot of computation or I/O on cleanup.
The slot returns immediately: it does not wait until the process has finished. When the process terminates, the processExited() signal is emitted.
Definition at line 1022 of file q3process_unix.cpp.
References d, QProc::pid, and Q3ProcessPrivate::proc.
Referenced by tryTerminate().
| void Q3Process::writeToStdin | ( | const QByteArray & | buf | ) | [virtual, slot] |
Writes the data buf to the process's standard input. The process may or may not read this data.
This function returns immediately; the Q3Process class might write the data at a later point (you must enter the event loop for this to occur). When all the data is written to the process, the signal wroteToStdin() is emitted. This does not mean that the process actually read the data, since this class only detects when it was able to write the data to the operating system.
Definition at line 1120 of file q3process_unix.cpp.
References buf, d, Q3PtrQueue< type >::enqueue(), Q3ProcessPrivate::notifierStdin, QSocketNotifier::setEnabled(), and Q3ProcessPrivate::stdinBuf.
Referenced by launch(), and writeToStdin().
01121 { 01122 #if defined(QT_Q3PROCESS_DEBUG) 01123 // qDebug( "Q3Process::writeToStdin(): write to stdin (%d)", d->socketStdin ); 01124 #endif 01125 d->stdinBuf.enqueue( new QByteArray(buf) ); 01126 if ( d->notifierStdin != 0 ) 01127 d->notifierStdin->setEnabled( true ); 01128 }
| void Q3Process::writeToStdin | ( | const QString & | buf | ) | [virtual, slot] |
This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. The string buf is handled as text using the QString::local8Bit() representation.
Definition at line 678 of file q3process.cpp.
References buf, QByteArray::resize(), and writeToStdin().
00679 { 00680 QByteArray tmp = buf.local8Bit(); 00681 tmp.resize( buf.length() ); 00682 writeToStdin( tmp ); 00683 }
| void Q3Process::closeStdin | ( | ) | [virtual, slot] |
Closes the process's standard input.
This function also deletes any pending data that has not been written to standard input.
Definition at line 1139 of file q3process_unix.cpp.
References d, Q3PtrQueue< type >::dequeue(), Q3PtrQueue< type >::isEmpty(), Q3ProcessPrivate::notifierStdin, Q3ProcessPrivate::proc, qDebug(), qWarning(), QProc::socketStdin, and Q3ProcessPrivate::stdinBuf.
Referenced by closeStdinLaunch(), and launch().
01140 { 01141 if ( d->proc == 0 ) 01142 return; 01143 if ( d->proc->socketStdin !=0 ) { 01144 while ( !d->stdinBuf.isEmpty() ) { 01145 delete d->stdinBuf.dequeue(); 01146 } 01147 delete d->notifierStdin; 01148 d->notifierStdin = 0; 01149 if ( ::close( d->proc->socketStdin ) != 0 ) { 01150 qWarning( "Could not close stdin of child process" ); 01151 } 01152 #if defined(QT_Q3PROCESS_DEBUG) 01153 qDebug( "Q3Process::closeStdin(): stdin (%d) closed", d->proc->socketStdin ); 01154 #endif 01155 d->proc->socketStdin = 0; 01156 } 01157 }
| void Q3Process::connectNotify | ( | const char * | signal | ) | [protected, virtual] |
Reimplemented from QObject.
Definition at line 696 of file q3process.cpp.
References ioRedirection, notifyOnExit, processExited(), qDebug(), qstrcmp(), readyReadStderr(), readyReadStdout(), setIoRedirection(), setNotifyOnExit(), setWroteStdinConnected(), SIGNAL, wroteToStdin(), and wroteToStdinConnected.
00697 { 00698 #if defined(QT_Q3PROCESS_DEBUG) 00699 qDebug( "Q3Process::connectNotify(): signal %s has been connected", signal ); 00700 #endif 00701 if ( !ioRedirection ) 00702 if ( qstrcmp( signal, SIGNAL(readyReadStdout()) )==0 || 00703 qstrcmp( signal, SIGNAL(readyReadStderr()) )==0 00704 ) { 00705 #if defined(QT_Q3PROCESS_DEBUG) 00706 qDebug( "Q3Process::connectNotify(): set ioRedirection to true" ); 00707 #endif 00708 setIoRedirection( true ); 00709 return; 00710 } 00711 if ( !notifyOnExit && qstrcmp( signal, SIGNAL(processExited()) )==0 ) { 00712 #if defined(QT_Q3PROCESS_DEBUG) 00713 qDebug( "Q3Process::connectNotify(): set notifyOnExit to true" ); 00714 #endif 00715 setNotifyOnExit( true ); 00716 return; 00717 } 00718 if ( !wroteToStdinConnected && qstrcmp( signal, SIGNAL(wroteToStdin()) )==0 ) { 00719 #if defined(QT_Q3PROCESS_DEBUG) 00720 qDebug( "Q3Process::connectNotify(): set wroteToStdinConnected to true" ); 00721 #endif 00722 setWroteStdinConnected( true ); 00723 return; 00724 } 00725 }
Here is the call graph for this function:

| void Q3Process::disconnectNotify | ( | const char * | signal | ) | [protected, virtual] |
Reimplemented from QObject.
Definition at line 729 of file q3process.cpp.
References ioRedirection, notifyOnExit, processExited(), qDebug(), readyReadStderr(), readyReadStdout(), QObject::receivers(), setIoRedirection(), setNotifyOnExit(), setWroteStdinConnected(), SIGNAL, wroteToStdin(), and wroteToStdinConnected.
00730 { 00731 if ( ioRedirection && 00732 receivers( SIGNAL(readyReadStdout()) ) ==0 && 00733 receivers( SIGNAL(readyReadStderr()) ) ==0 00734 ) { 00735 #if defined(QT_Q3PROCESS_DEBUG) 00736 qDebug( "Q3Process::disconnectNotify(): set ioRedirection to false" ); 00737 #endif 00738 setIoRedirection( false ); 00739 } 00740 if ( notifyOnExit && receivers( SIGNAL(processExited()) ) == 0 ) { 00741 #if defined(QT_Q3PROCESS_DEBUG) 00742 qDebug( "Q3Process::disconnectNotify(): set notifyOnExit to false" ); 00743 #endif 00744 setNotifyOnExit( false ); 00745 } 00746 if ( wroteToStdinConnected && receivers( SIGNAL(wroteToStdin()) ) == 0 ) { 00747 #if defined(QT_Q3PROCESS_DEBUG) 00748 qDebug( "Q3Process::disconnectNotify(): set wroteToStdinConnected to false" ); 00749 #endif 00750 setWroteStdinConnected( false ); 00751 } 00752 }
Here is the call graph for this function:

| void Q3Process::setIoRedirection | ( | bool | value | ) | [private] |
Definition at line 1330 of file q3process_unix.cpp.
References d, ioRedirection, Q3ProcessPrivate::notifierStderr, Q3ProcessPrivate::notifierStdout, and QSocketNotifier::setEnabled().
Referenced by connectNotify(), and disconnectNotify().
01331 { 01332 ioRedirection = value; 01333 if ( ioRedirection ) { 01334 if ( d->notifierStdout ) 01335 d->notifierStdout->setEnabled( true ); 01336 if ( d->notifierStderr ) 01337 d->notifierStderr->setEnabled( true ); 01338 } else { 01339 if ( d->notifierStdout ) 01340 d->notifierStdout->setEnabled( false ); 01341 if ( d->notifierStderr ) 01342 d->notifierStderr->setEnabled( false ); 01343 } 01344 }
| void Q3Process::setNotifyOnExit | ( | bool | value | ) | [private] |
Definition at line 1351 of file q3process_unix.cpp.
References notifyOnExit.
Referenced by connectNotify(), and disconnectNotify().
01352 { 01353 notifyOnExit = value; 01354 }
| void Q3Process::setWroteStdinConnected | ( | bool | value | ) | [private] |
Definition at line 1360 of file q3process_unix.cpp.
References wroteToStdinConnected.
Referenced by connectNotify(), and disconnectNotify().
01361 { 01362 wroteToStdinConnected = value; 01363 }
| void Q3Process::init | ( | ) | [private] |
Definition at line 561 of file q3process_unix.cpp.
References d, exitNormal, exitStat, and Q3ProcessPrivate.
Referenced by Q3Process().
00562 { 00563 d = new Q3ProcessPrivate(); 00564 exitStat = 0; 00565 exitNormal = false; 00566 }
| void Q3Process::reset | ( | ) | [private] |
Definition at line 572 of file q3process_unix.cpp.
References Q3ProcessPrivate::bufStderr, Q3ProcessPrivate::bufStdout, Q3Membuf::clear(), d, exitNormal, exitStat, and Q3ProcessPrivate.
Referenced by start().
00573 { 00574 delete d; 00575 d = new Q3ProcessPrivate(); 00576 exitStat = 0; 00577 exitNormal = false; 00578 d->bufStdout.clear(); 00579 d->bufStderr.clear(); 00580 }
Here is the call graph for this function:

| Q3Membuf * Q3Process::membufStdout | ( | ) | [private] |
Definition at line 582 of file q3process_unix.cpp.
References Q3ProcessPrivate::bufStdout, d, Q3ProcessPrivate::proc, socketRead(), and QProc::socketStdout.
Referenced by canReadLineStdout(), readLineStdout(), and readStdout().
00583 { 00584 if ( d->proc && d->proc->socketStdout ) { 00585 /* 00586 Apparently, there is not consistency among different 00587 operating systems on how to use FIONREAD. 00588 00589 FreeBSD, Linux and Solaris all expect the 3rd argument to 00590 ioctl() to be an int, which is normally 32-bit even on 00591 64-bit machines. 00592 00593 IRIX, on the other hand, expects a size_t, which is 64-bit 00594 on 64-bit machines. 00595 00596 So, the solution is to use size_t initialized to zero to 00597 make sure all bits are set to zero, preventing underflow 00598 with the FreeBSD/Linux/Solaris ioctls. 00599 */ 00600 size_t nbytes = 0; 00601 if ( ::ioctl(d->proc->socketStdout, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) 00602 socketRead( d->proc->socketStdout ); 00603 } 00604 return &d->bufStdout; 00605 }
| Q3Membuf * Q3Process::membufStderr | ( | ) | [private] |
Definition at line 607 of file q3process_unix.cpp.
References Q3ProcessPrivate::bufStderr, d, Q3ProcessPrivate::proc, socketRead(), and QProc::socketStderr.
Referenced by canReadLineStderr(), readLineStderr(), and readStderr().
00608 { 00609 if ( d->proc && d->proc->socketStderr ) { 00610 /* 00611 Apparently, there is not consistency among different 00612 operating systems on how to use FIONREAD. 00613 00614 FreeBSD, Linux and Solaris all expect the 3rd argument to 00615 ioctl() to be an int, which is normally 32-bit even on 00616 64-bit machines. 00617 00618 IRIX, on the other hand, expects a size_t, which is 64-bit 00619 on 64-bit machines. 00620 00621 So, the solution is to use size_t initialized to zero to 00622 make sure all bits are set to zero, preventing underflow 00623 with the FreeBSD/Linux/Solaris ioctls. 00624 */ 00625 size_t nbytes = 0; 00626 if ( ::ioctl(d->proc->socketStderr, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) 00627 socketRead( d->proc->socketStderr ); 00628 } 00629 return &d->bufStderr; 00630 }
| void Q3Process::socketRead | ( | int | fd | ) | [private, slot] |
Definition at line 1164 of file q3process_unix.cpp.
References buffer, Q3ProcessPrivate::bufStderr, Q3ProcessPrivate::bufStdout, d, QByteArray::data(), emit, n, Q3ProcessPrivate::notifierStderr, Q3ProcessPrivate::notifierStdout, Q3ProcessPrivate::proc, qDebug(), readyReadStderr(), readyReadStdout(), QByteArray::resize(), QSocketNotifier::setEnabled(), Q3ProcessPrivate::socketReadCalled, QProc::socketStderr, and QProc::socketStdout.
Referenced by membufStderr(), membufStdout(), Q3ProcessManager::sigchldHnd(), and start().
01165 { 01166 if ( d->socketReadCalled ) { 01167 // the slots that are connected to the readyRead...() signals might 01168 // trigger a recursive call of socketRead(). Avoid this since you get a 01169 // blocking read otherwise. 01170 return; 01171 } 01172 01173 #if defined(QT_Q3PROCESS_DEBUG) 01174 qDebug( "Q3Process::socketRead(): %d", fd ); 01175 #endif 01176 if ( fd == 0 ) 01177 return; 01178 if ( !d->proc ) 01179 return; 01180 Q3Membuf *buffer = 0; 01181 int n; 01182 if ( fd == d->proc->socketStdout ) { 01183 buffer = &d->bufStdout; 01184 } else if ( fd == d->proc->socketStderr ) { 01185 buffer = &d->bufStderr; 01186 } else { 01187 // this case should never happen, but just to be safe 01188 return; 01189 } 01190 #if defined(QT_Q3PROCESS_DEBUG) 01191 uint oldSize = buffer->size(); 01192 #endif 01193 01194 // try to read data first (if it fails, the filedescriptor was closed) 01195 const int basize = 4096; 01196 QByteArray *ba = new QByteArray( basize ); 01197 n = ::read( fd, ba->data(), basize ); 01198 if ( n > 0 ) { 01199 ba->resize( n ); 01200 buffer->append( ba ); 01201 ba = 0; 01202 } else { 01203 delete ba; 01204 ba = 0; 01205 } 01206 // eof or error? 01207 if ( n == 0 || n == -1 ) { 01208 if ( fd == d->proc->socketStdout ) { 01209 #if defined(QT_Q3PROCESS_DEBUG) 01210 qDebug( "Q3Process::socketRead(): stdout (%d) closed", fd ); 01211 #endif 01212 d->notifierStdout->setEnabled( false ); 01213 delete d->notifierStdout; 01214 d->notifierStdout = 0; 01215 ::close( d->proc->socketStdout ); 01216 d->proc->socketStdout = 0; 01217 return; 01218 } else if ( fd == d->proc->socketStderr ) { 01219 #if defined(QT_Q3PROCESS_DEBUG) 01220 qDebug( "Q3Process::socketRead(): stderr (%d) closed", fd ); 01221 #endif 01222 d->notifierStderr->setEnabled( false ); 01223 delete d->notifierStderr; 01224 d->notifierStderr = 0; 01225 ::close( d->proc->socketStderr ); 01226 d->proc->socketStderr = 0; 01227 return; 01228 } 01229 } 01230 01231 if ( fd < FD_SETSIZE ) { 01232 fd_set fds; 01233 struct timeval tv; 01234 FD_ZERO( &fds ); 01235 FD_SET( fd, &fds ); 01236 tv.tv_sec = 0; 01237 tv.tv_usec = 0; 01238 while ( ::select( fd+1, &fds, 0, 0, &tv ) > 0 ) { 01239 // prepare for the next round 01240 FD_ZERO( &fds ); 01241 FD_SET( fd, &fds ); 01242 // read data 01243 ba = new QByteArray( basize ); 01244 n = ::read( fd, ba->data(), basize ); 01245 if ( n > 0 ) { 01246 ba->resize( n ); 01247 buffer->append( ba ); 01248 ba = 0; 01249 } else { 01250 delete ba; 01251 ba = 0; 01252 break; 01253 } 01254 } 01255 } 01256 01257 d->socketReadCalled = true; 01258 if ( fd == d->proc->socketStdout ) { 01259 #if defined(QT_Q3PROCESS_DEBUG) 01260 qDebug( "Q3Process::socketRead(): %d bytes read from stdout (%d)", 01261 buffer->size()-oldSize, fd ); 01262 #endif 01263 emit readyReadStdout(); 01264 } else if ( fd == d->proc->socketStderr ) { 01265 #if defined(QT_Q3PROCESS_DEBUG) 01266 qDebug( "Q3Process::socketRead(): %d bytes read from stderr (%d)", 01267 buffer->size()-oldSize, fd ); 01268 #endif 01269 emit readyReadStderr(); 01270 } 01271 d->socketReadCalled = false; 01272 }
| void Q3Process::socketWrite | ( | int | fd | ) | [private, slot] |
Definition at line 1279 of file q3process_unix.cpp.
References d, QByteArray::data(), Q3PtrQueue< type >::dequeue(), emit, Q3PtrQueue< type >::head(), Q3PtrQueue< type >::isEmpty(), Q3ProcessPrivate::notifierStdin, Q3ProcessPrivate::proc, qDebug(), QSocketNotifier::setEnabled(), QByteArray::size(), QProc::socketStdin, Q3ProcessPrivate::stdinBuf, Q3ProcessPrivate::stdinBufRead, wroteToStdin(), and wroteToStdinConnected.
Referenced by flushStdin(), and start().
01280 { 01281 while ( fd == d->proc->socketStdin && d->proc->socketStdin != 0 ) { 01282 if ( d->stdinBuf.isEmpty() ) { 01283 d->notifierStdin->setEnabled( false ); 01284 return; 01285 } 01286 ssize_t ret = ::write( fd, 01287 d->stdinBuf.head()->data() + d->stdinBufRead, 01288 d->stdinBuf.head()->size() - d->stdinBufRead ); 01289 #if defined(QT_Q3PROCESS_DEBUG) 01290 qDebug( "Q3Process::socketWrite(): wrote %d bytes to stdin (%d)", ret, fd ); 01291 #endif 01292 if ( ret == -1 ) 01293 return; 01294 d->stdinBufRead += ret; 01295 if ( d->stdinBufRead == (ssize_t)d->stdinBuf.head()->size() ) { 01296 d->stdinBufRead = 0; 01297 delete d->stdinBuf.dequeue(); 01298 if ( wroteToStdinConnected && d->stdinBuf.isEmpty() ) 01299 emit wroteToStdin(); 01300 } 01301 } 01302 }
| void Q3Process::timeout | ( | ) | [private, slot] |
| void Q3Process::closeStdinLaunch | ( | ) | [private, slot] |
Definition at line 613 of file q3process.cpp.
References closeStdin(), QObject::disconnect(), emit, launchFinished(), SIGNAL, SLOT, and wroteToStdin().
Referenced by launch().
00614 { 00615 disconnect( this, SIGNAL(wroteToStdin()), 00616 this, SLOT(closeStdinLaunch()) ); 00617 closeStdin(); 00618 emit launchFinished(); 00619 }
friend class Q3ProcessPrivate [friend] |
Q3ProcessPrivate* Q3Process::d [private] |
Definition at line 132 of file q3process.h.
Referenced by canReadLineStderr(), canReadLineStdout(), closeStdin(), flushStdin(), init(), isRunning(), kill(), membufStderr(), membufStdout(), processIdentifier(), reset(), setIoRedirection(), Q3ProcessManager::sigchldHnd(), socketRead(), socketWrite(), start(), tryTerminate(), writeToStdin(), ~Q3Process(), and QProc::~QProc().
QDir Q3Process::workingDir [private] |
Definition at line 134 of file q3process.h.
Referenced by setWorkingDirectory(), start(), and workingDirectory().
QStringList Q3Process::_arguments [private] |
Definition at line 136 of file q3process.h.
Referenced by addArgument(), arguments(), clearArguments(), setArguments(), and start().
int Q3Process::exitStat [private] |
Definition at line 138 of file q3process.h.
Referenced by exitStatus(), init(), isRunning(), and reset().
bool Q3Process::exitNormal [private] |
Definition at line 139 of file q3process.h.
Referenced by init(), isRunning(), normalExit(), and reset().
bool Q3Process::ioRedirection [private] |
Definition at line 140 of file q3process.h.
Referenced by connectNotify(), disconnectNotify(), setIoRedirection(), and start().
bool Q3Process::notifyOnExit [private] |
Definition at line 141 of file q3process.h.
Referenced by connectNotify(), disconnectNotify(), setNotifyOnExit(), and Q3ProcessManager::sigchldHnd().
bool Q3Process::wroteToStdinConnected [private] |
Definition at line 142 of file q3process.h.
Referenced by connectNotify(), disconnectNotify(), setWroteStdinConnected(), and socketWrite().
bool Q3Process::readStdoutCalled [private] |
bool Q3Process::readStderrCalled [private] |
int Q3Process::comms [private] |
Definition at line 146 of file q3process.h.
Referenced by communication(), setCommunication(), and start().
1.5.1