-rw-r--r-- | libopie2/opiecore/oprocess.h | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/libopie2/opiecore/oprocess.h b/libopie2/opiecore/oprocess.h index 1a2472d..eb56b03 100644 --- a/libopie2/opiecore/oprocess.h +++ b/libopie2/opiecore/oprocess.h @@ -1,142 +1,148 @@ /* This file is part of the Opie Project Copyright (C) 2003-2004 Holger Freyther <zecke@handhelds.org> Copyright (C) The Opie Team <opie-devel@handhelds.org> =. Based on KProcess (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at) .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef OPROCESS_H #define OPROCESS_H /* QT */ #include <qcstring.h> #include <qobject.h> #include <qvaluelist.h> /* STD */ #include <sys/types.h> // for pid_t #include <sys/wait.h> #include <signal.h> #include <unistd.h> class QSocketNotifier; + +namespace Opie { +namespace Core { +namespace Private { +class OProcessController; class OProcessPrivate; +} /** * Child process invocation, monitoring and control. * * @sect General usage and features * *This class allows a KDE and OPIE application to start child processes without having *to worry about UN*X signal handling issues and zombie process reaping. * *@see KProcIO * *Basically, this class distinguishes three different ways of running *child processes: * *@li OProcess::DontCare -- The child process is invoked and both the child *process and the parent process continue concurrently. * *Starting a DontCare child process means that the application is *not interested in any notification to determine whether the *child process has already exited or not. * *@li OProcess::NotifyOnExit -- The child process is invoked and both the *child and the parent process run concurrently. * *When the child process exits, the OProcess instance *corresponding to it emits the Qt signal @ref processExited(). * *Since this signal is @em not emitted from within a UN*X *signal handler, arbitrary function calls can be made. * *Be aware: When the OProcess objects gets destructed, the child *process will be killed if it is still running! *This means in particular, that you cannot use a OProcess on the stack *with OProcess::NotifyOnExit. * *@li OProcess::Block -- The child process starts and the parent process *is suspended until the child process exits. (@em Really not recommended *for programs with a GUI.) * *OProcess also provides several functions for determining the exit status *and the pid of the child process it represents. * *Furthermore it is possible to supply command-line arguments to the process *in a clean fashion (no null -- terminated stringlists and such...) * *A small usage example: *<pre> *OProcess *proc = new OProcess; * **proc << "my_executable"; **proc << "These" << "are" << "the" << "command" << "line" << "args"; *QApplication::connect(proc, SIGNAL(processExited(OProcess *)), * pointer_to_my_object, SLOT(my_objects_slot(OProcess *))); *proc->start(); *</pre> * *This will start "my_executable" with the commandline arguments "These"... * *When the child process exits, the respective Qt signal will be emitted. * *@sect Communication with the child process * *OProcess supports communication with the child process through *stdin/stdout/stderr. * *The following functions are provided for getting data from the child *process or sending data to the child's stdin (For more information, *have a look at the documentation of each function): * *@li bool @ref writeStdin(char *buffer, int buflen); *@li -- Transmit data to the child process's stdin. * *@li bool @ref closeStdin(); *@li -- Closes the child process's stdin (which causes it to see an feof(stdin)). *Returns false if you try to close stdin for a process that has been started *without a communication channel to stdin. * *@li bool @ref closeStdout(); *@li -- Closes the child process's stdout. *Returns false if you try to close stdout for a process that has been started *without a communication channel to stdout. * *@li bool @ref closeStderr(); *@li -- Closes the child process's stderr. *Returns false if you try to close stderr for a process that has been started *without a communication channel to stderr. * * *@sect QT signals: * *@li void @ref receivedStdout(OProcess *proc, char *buffer, int buflen); *@li void @ref receivedStderr(OProcess *proc, char *buffer, int buflen); *@li -- Indicates that new data has arrived from either the *child process's stdout or stderr. * *@li void @ref wroteStdin(OProcess *proc); @@ -304,192 +310,193 @@ public: * the process has exited, it returns the process id of the last * child process that was created by this instance of OProcess. * * Calling it before any child process has been started by this * OProcess instance causes pid() to return 0. **/ pid_t pid() const; /** * Suspend processing of data from stdout of the child process. */ void suspend(); /** * Resume processing of data from stdout of the child process. */ void resume(); /** * @return @p true if the process has already finished and has exited * "voluntarily", ie: it has not been killed by a signal. * * Note that you should check @ref OProcess::exitStatus() to determine * whether the process completed its task successful or not. */ bool normalExit() const; /** * Returns the exit status of the process. * * Please use * @ref OProcess::normalExit() to check whether the process has exited * cleanly (i.e., @ref OProcess::normalExit() returns @p true) before calling * this function because if the process did not exit normally, * it does not have a valid exit status. */ int exitStatus() const; /** * Transmit data to the child process's stdin. * * OProcess::writeStdin may return false in the following cases: * * @li The process is not currently running. * * @li Communication to stdin has not been requested in the @ref start() call. * * @li Transmission of data to the child process by a previous call to * @ref writeStdin() is still in progress. * * Please note that the data is sent to the client asynchronously, * so when this function returns, the data might not have been * processed by the child process. * * If all the data has been sent to the client, the signal * @ref wroteStdin() will be emitted. * * Please note that you must not free "buffer" or call @ref writeStdin() * again until either a @ref wroteStdin() signal indicates that the * data has been sent or a @ref processHasExited() signal shows that * the child process is no longer alive... **/ bool writeStdin( const char *buffer, int buflen ); void flushStdin(); /** * This causes the stdin file descriptor of the child process to be * closed indicating an "EOF" to the child. * * @return @p false if no communication to the process's stdin * had been specified in the call to @ref start(). */ bool closeStdin(); /** * This causes the stdout file descriptor of the child process to be * closed. * * @return @p false if no communication to the process's stdout * had been specified in the call to @ref start(). */ bool closeStdout(); /** * This causes the stderr file descriptor of the child process to be * closed. * * @return @p false if no communication to the process's stderr * had been specified in the call to @ref start(). */ bool closeStderr(); /** * Lets you see what your arguments are for debugging. + * \todo make const */ const QValueList<QCString> &args() { return arguments; } /** * Controls whether the started process should drop any * setuid/segid privileges or whether it should keep them * * The default is @p false : drop privileges */ void setRunPrivileged( bool keepPrivileges ); /** * Returns whether the started process will drop any * setuid/segid privileges or whether it will keep them */ bool runPrivileged() const; /** * Modifies the environment of the process to be started. * This function must be called before starting the process. */ void setEnvironment( const QString &name, const QString &value ); /** * Changes the current working directory (CWD) of the process * to be started. * This function must be called before starting the process. */ void setWorkingDirectory( const QString &dir ); /** * Specify whether to start the command via a shell or directly. * The default is to start the command directly. * If @p useShell is true @p shell will be used as shell, or * if shell is empty, the standard shell is used. * @p quote A flag indicating whether to quote the arguments. * * When using a shell, the caller should make sure that all filenames etc. * are properly quoted when passed as argument. * @see quote() */ void setUseShell( bool useShell, const char *shell = 0 ); /** * This function can be used to quote an argument string such that * the shell processes it properly. This is e. g. necessary for * user-provided file names which may contain spaces or quotes. * It also prevents expansion of wild cards and environment variables. */ static QString quote( const QString &arg ); /** * Detaches OProcess from child process. All communication is closed. * No exit notification is emitted any more for the child process. * Deleting the OProcess will no longer kill the child process. * Note that the current process remains the parent process of the * child process. */ void detach(); /** * @return the PID of @a process, or -1 if the process is not running */ static int processPID( const QString& process ); signals: /** * Emitted after the process has terminated when * the process was run in the @p NotifyOnExit (==default option to * @ref start()) or the @ref Block mode. **/ void processExited( OProcess *proc ); /** * Emitted, when output from the child process has * been received on stdout. * * To actually get * these signals, the respective communication link (stdout/stderr) * has to be turned on in @ref start(). * * @param buffer The data received. * @param buflen The number of bytes that are available. * * You should copy the information contained in @p buffer to your private * data structures before returning from this slot. **/ void receivedStdout( OProcess *proc, char *buffer, int buflen ); /** @@ -623,130 +630,132 @@ protected: /** * This function is called from "OProcess::start" right before a "fork" takes * place. According to * the "comm" parameter this function has to initialize the "in", "out" and * "err" data member of OProcess. * * This function should return 0 if setting the needed communication channels * was successful. * * The default implementation is to create UNIX STREAM sockets for the communication, * but you could overload this function and establish a TCP/IP communication for * network communication, for example. */ virtual int setupCommunication( Communication comm ); /** * Called right after a (successful) fork on the parent side. This function * will usually do some communications cleanup, like closing the reading end * of the "stdin" communication channel. * * Furthermore, it must also create the QSocketNotifiers "innot", "outnot" and * "errnot" and connect their Qt slots to the respective OProcess member functions. * * For a more detailed explanation, it is best to have a look at the default * implementation of "setupCommunication" in kprocess.cpp. */ virtual int commSetupDoneP(); /** * Called right after a (successful) fork, but before an "exec" on the child * process' side. It usually just closes the unused communication ends of * "in", "out" and "err" (like the writing end of the "in" communication * channel. */ virtual int commSetupDoneC(); /** * Immediately called after a process has exited. This function normally * calls commClose to close all open communication channels to this * process and emits the "processExited" signal (if the process was * not running in the "DontCare" mode). */ virtual void processHasExited( int state ); /** * Should clean up the communication links to the child after it has * exited. Should be called from "processHasExited". */ virtual void commClose(); /** * the socket descriptors for stdin/stdout/stderr. */ int out[ 2 ]; int in[ 2 ]; int err[ 2 ]; /** * The socket notifiers for the above socket descriptors. */ QSocketNotifier *innot; QSocketNotifier *outnot; QSocketNotifier *errnot; /** * Lists the communication links that are activated for the child * process. Should not be modified from derived classes. */ Communication communication; /** * Called by "slotChildOutput" this function copies data arriving from the * child process's stdout to the respective buffer and emits the signal * "@ref receivedStderr". */ int childOutput( int fdno ); /** * Called by "slotChildOutput" this function copies data arriving from the * child process's stdout to the respective buffer and emits the signal * "@ref receivedStderr" */ int childError( int fdno ); // information about the data that has to be sent to the child: const char *input_data; // the buffer holding the data int input_sent; // # of bytes already transmitted int input_total; // total length of input_data /** * @ref OProcessController is a friend of OProcess because it has to have * access to various data members. */ - friend class OProcessController; + friend class Private::OProcessController; private: /** * Searches for a valid shell. * Here is the algorithm used for finding an executable shell: * * @li Try the executable pointed to by the "SHELL" environment * variable with white spaces stripped off * * @li If your process runs with uid != euid or gid != egid, a shell * not listed in /etc/shells will not used. * * @li If no valid shell could be found, "/bin/sh" is used as a last resort. */ QCString searchShell(); /** * Used by @ref searchShell in order to find out whether the shell found * is actually executable at all. */ bool isExecutable( const QCString &filename ); // Disallow assignment and copy-construction OProcess( const OProcess& ); OProcess& operator= ( const OProcess& ); private: void init ( ); - OProcessPrivate *d; + Private::OProcessPrivate *d; }; +} +} #endif |