diff options
Diffstat (limited to 'tdecore')
-rw-r--r-- | tdecore/CMakeLists.txt | 4 | ||||
-rw-r--r-- | tdecore/MAINTAINERS | 2 | ||||
-rw-r--r-- | tdecore/Makefile.am | 4 | ||||
-rw-r--r-- | tdecore/kprocctrl.cpp | 2 | ||||
-rw-r--r-- | tdecore/kprocctrl.h | 2 | ||||
-rw-r--r-- | tdecore/kprocess.h | 940 | ||||
-rw-r--r-- | tdecore/kprocio.h | 2 | ||||
-rw-r--r-- | tdecore/kpty.cpp | 2 | ||||
-rw-r--r-- | tdecore/ktempdir.cpp | 2 | ||||
-rw-r--r-- | tdecore/ktimezones.cpp | 2 | ||||
-rw-r--r-- | tdecore/tdeconfigbackend.cpp | 2 | ||||
-rw-r--r-- | tdecore/tdeprocess.cpp (renamed from tdecore/kprocess.cpp) | 6 | ||||
-rw-r--r-- | tdecore/tdeprocess.h | 936 | ||||
-rw-r--r-- | tdecore/tdesycoca.cpp | 2 | ||||
-rw-r--r-- | tdecore/tests/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tdecore/tests/Makefile.am | 6 | ||||
-rw-r--r-- | tdecore/tests/kprociotest.cpp | 2 | ||||
-rw-r--r-- | tdecore/tests/tdeprocesstest.cpp (renamed from tdecore/tests/kprocesstest.cpp) | 8 | ||||
-rw-r--r-- | tdecore/tests/tdeprocesstest.h (renamed from tdecore/tests/kprocesstest.h) | 4 |
19 files changed, 963 insertions, 967 deletions
diff --git a/tdecore/CMakeLists.txt b/tdecore/CMakeLists.txt index 4e36f0978..18ce4eda9 100644 --- a/tdecore/CMakeLists.txt +++ b/tdecore/CMakeLists.txt @@ -53,7 +53,7 @@ install( FILES tdeconfigdialogmanager.h tdeconfigbase.h kdesktopfile.h kurl.h ksock.h tdeaboutdata.h tdecmdlineargs.h tdeconfigbackend.h tdeapplication.h tdeuniqueapplication.h - kcharsets.h tdeversion.h kpty.h kprocess.h kprocctrl.h + kcharsets.h tdeversion.h kpty.h kprocess.h tdeprocess.h kprocctrl.h tdelocale.h kicontheme.h kiconloader.h kdebug.h twinmodule.h twin.h krootprop.h tdeshortcut.h kkeynative.h tdeaccel.h kglobalaccel.h tdestdaccel.h tdeshortcutlist.h kcatalogue.h @@ -108,7 +108,7 @@ set( ${target}_SRCS libintl.cpp tdeapplication.cpp kdebug.cpp netwm.cpp tdeconfigbase.cpp tdeconfig.cpp ksimpleconfig.cpp tdeconfigbackend.cpp kmanagerselection.cpp kdesktopfile.cpp kstandarddirs.cpp - ksock.cpp kpty.cpp kprocess.cpp kprocctrl.cpp tdelocale.cpp + ksock.cpp kpty.cpp tdeprocess.cpp kprocctrl.cpp tdelocale.cpp krfcdate.cpp kiconeffect.cpp kicontheme.cpp kiconloader.cpp twin.cpp twinmodule.cpp krootprop.cpp kcharsets.cpp kckey.cpp tdeshortcut.cpp kkeynative_x11.cpp kkeyserver_x11.cpp diff --git a/tdecore/MAINTAINERS b/tdecore/MAINTAINERS index 441274b09..d7012b321 100644 --- a/tdecore/MAINTAINERS +++ b/tdecore/MAINTAINERS @@ -49,7 +49,7 @@ knotifyclient.cpp kpalette.cpp Waldo Bastian <bastian@kde.org> kpixmapprovider.cpp Carsten Pfeiffer <pfeiffer@kde.org> kprocctrl.cpp Waldo Bastian <bastian@kde.org> -kprocess.cpp Waldo Bastian <bastian@kde.org> +tdeprocess.cpp Waldo Bastian <bastian@kde.org> kprocio.cpp Waldo Bastian <bastian@kde.org> krandomsequence.cpp Waldo Bastian <bastian@kde.org> kregexp.cpp diff --git a/tdecore/Makefile.am b/tdecore/Makefile.am index b59c6fd52..ada41910c 100644 --- a/tdecore/Makefile.am +++ b/tdecore/Makefile.am @@ -40,7 +40,7 @@ include_HEADERS = tdeconfig.h tdeconfigskeleton.h \ tdeconfigdata.h ksimpleconfig.h tdeconfigdialogmanager.h \ tdeconfigbase.h kdesktopfile.h kurl.h ksock.h tdeaboutdata.h \ tdecmdlineargs.h tdeconfigbackend.h tdeapplication.h \ - tdeuniqueapplication.h kcharsets.h tdeversion.h kpty.h kprocess.h \ + tdeuniqueapplication.h kcharsets.h tdeversion.h kpty.h kprocess.h tdeprocess.h \ kprocctrl.h tdelocale.h kicontheme.h kiconloader.h kdebug.h \ twinmodule.h twin.h krootprop.h tdeshortcut.h kkeynative.h tdeaccel.h \ kglobalaccel.h tdestdaccel.h tdeshortcutlist.h kcatalogue.h \ @@ -92,7 +92,7 @@ noinst_HEADERS = tdeaccelaction.h tdeaccelbase.h tdeaccelprivate.h kckey.h \ libtdecore_la_SOURCES = libintl.cpp tdeapplication.cpp \ kdebug.cpp netwm.cpp tdeconfigbase.cpp tdeconfig.cpp ksimpleconfig.cpp \ tdeconfigbackend.cpp kmanagerselection.cpp kdesktopfile.cpp \ - kstandarddirs.cpp ksock.cpp kpty.cpp kprocess.cpp kprocctrl.cpp \ + kstandarddirs.cpp ksock.cpp kpty.cpp tdeprocess.cpp kprocctrl.cpp \ tdelocale.cpp krfcdate.cpp kiconeffect.cpp kicontheme.cpp \ kiconloader.cpp twin.cpp twinmodule.cpp krootprop.cpp kcharsets.cpp \ kckey.cpp tdeshortcut.cpp kkeynative_x11.cpp kkeyserver_x11.cpp \ diff --git a/tdecore/kprocctrl.cpp b/tdecore/kprocctrl.cpp index 720778d4e..471642ddb 100644 --- a/tdecore/kprocctrl.cpp +++ b/tdecore/kprocctrl.cpp @@ -17,7 +17,7 @@ Boston, MA 02110-1301, USA. */ -#include "kprocess.h" +#include "tdeprocess.h" #include "kprocctrl.h" #include <config.h> diff --git a/tdecore/kprocctrl.h b/tdecore/kprocctrl.h index ac5700753..ddd59179b 100644 --- a/tdecore/kprocctrl.h +++ b/tdecore/kprocctrl.h @@ -22,7 +22,7 @@ #include <tqvaluelist.h> -#include "kprocess.h" +#include "tdeprocess.h" class TQSocketNotifier; diff --git a/tdecore/kprocess.h b/tdecore/kprocess.h index 211e3cc7f..216868501 100644 --- a/tdecore/kprocess.h +++ b/tdecore/kprocess.h @@ -1,939 +1 @@ -/* This file is part of the KDE libraries - Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef __kprocess_h__ -#define __kprocess_h__ - -#include <sys/types.h> // for pid_t -#include <sys/wait.h> -#include <signal.h> -#include <unistd.h> -#include <tqvaluelist.h> -#include <tqcstring.h> -#include <tqobject.h> -#include "tdelibs_export.h" - -class TQSocketNotifier; -class TDEProcessPrivate; - -#ifdef Q_OS_UNIX -#include <kpty.h> -#else -class KPty; -#endif - -/** - * Child process invocation, monitoring and control. - * This class works only in the application's main thread. - * - * <b>General usage and features:</b>\n - * - * This class allows a KDE 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 DontCare -- The child process is invoked and both the child - * process and the parent process continue concurrently. - * - * The process is started in an own session (see setsid(2)). - * - * @li NotifyOnExit -- The child process is invoked and both the - * child and the parent process run concurrently. - * - * When the child process exits, the TDEProcess instance - * corresponding to it emits the Qt signal 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 TDEProcess object gets destructed, the child - * process will be killed if it is still running! - * This means in particular, that it usually makes no sense to use - * a TDEProcess on the stack with NotifyOnExit. - * - * @li OwnGroup -- like NotifyOnExit, but the child process is started - * in an own process group (and an own session, FWIW). The behavior of - * kill() changes to killing the whole process group - this makes - * this mode useful for implementing primitive job management. It can be - * used to work around broken wrapper scripts that don't propagate signals - * to the "real" program. However, use this with care, as you disturb the - * shell's job management if your program is started from the command line. - * - * @li 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.) - * In this mode the parent can read the child's output, but can't send it any - * input. - * - * TDEProcess 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: - * \code - * TDEProcess *proc = new TDEProcess; - * - * *proc << "my_executable"; - * *proc << "These" << "are" << "the" << "command" << "line" << "args"; - * TQApplication::connect(proc, TQ_SIGNAL(processExited(TDEProcess *)), - * pointer_to_my_object, TQ_SLOT(my_objects_slot(TDEProcess *))); - * proc->start(); - * \endcode - * - * This will start "my_executable" with the commandline arguments "These"... - * - * When the child process exits, the slot will be invoked. - * - * <b>Communication with the child process:</b>\n - * - * TDEProcess 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 writeStdin() - * -- Transmit data to the child process' stdin. When all data was sent, the - * signal wroteStdin() is emitted. - * - * @li When data arrives at stdout or stderr, the signal receivedStdout() - * resp. receivedStderr() is emitted. - * - * @li You can shut down individual communication channels with - * closeStdin(), closeStdout(), and closeStderr(), resp. - * - * @author Christian Czezatke e9025461@student.tuwien.ac.at - * - **/ -class TDECORE_EXPORT TDEProcess : public TQObject -{ - TQ_OBJECT - -public: - - /** - * Modes in which the communication channel can be opened. - * - * If communication for more than one channel is required, - * the values have to be or'ed together, for example to get - * communication with stdout as well as with stdin, you would - * specify @p Stdin | @p Stdout - * - * If @p NoRead is specified in conjunction with @p Stdout, - * no data is actually read from @p Stdout but only - * the signal receivedStdout(int fd, int &len) is emitted. - * - * @p CTtyOnly tells setUsePty() to create a PTY for the process - * and make it the process' controlling TTY, but does not redirect - * any I/O channel to the PTY. - * - * If @p MergedStderr is specified in conjunction with @p Stdout, - * Stderr will be redirected onto the same file handle as Stdout, - * i.e., all error output will be signalled with receivedStdout(). - * Don't specify @p Stderr if you specify @p MergedStderr. - */ - enum Communication { - NoCommunication = 0, - Stdin = 1, Stdout = 2, Stderr = 4, - AllOutput = 6, All = 7, - NoRead = 8, - CTtyOnly = NoRead, - MergedStderr = 16 - }; - - /** - * Run-modes for a child process. - */ - enum RunMode { - /** - * The application does not receive notifications from the subprocess when - * it is finished or aborted. - */ - DontCare, - /** - * The application is notified when the subprocess dies. - */ - NotifyOnExit, - /** - * The application is suspended until the started process is finished. - */ - Block, - /** - * Same as NotifyOnExit, but the process is run in an own session, - * just like with DontCare. - */ - OwnGroup - }; - - /** - * Constructor - * @since 3.2 - */ - TDEProcess( TQObject* parent, const char *name = 0 ); - - /** - * Constructor - */ // KDE4 merge with the above - TDEProcess(); - - /** - *Destructor: - * - * If the process is running when the destructor for this class - * is called, the child process is killed with a SIGKILL, but - * only if the run mode is not of type @p DontCare. - * Processes started as @p DontCare keep running anyway. - */ - virtual ~TDEProcess(); - - /** - @deprecated - Use operator<<() instead. - - Sets the executable to be started with this TDEProcess object. - Returns false if the process is currently running (in that - case the executable remains unchanged). - - @see operator<<() - - */ - bool setExecutable(const TQString& proc) TDE_DEPRECATED; - - - /** - * Sets the executable and the command line argument list for this process. - * - * For example, doing an "ls -l /usr/local/bin" can be achieved by: - * \code - * TDEProcess p; - * ... - * p << "ls" << "-l" << "/usr/local/bin" - * \endcode - * - * @param arg the argument to add - * @return a reference to this TDEProcess - **/ - TDEProcess &operator<<(const TQString& arg); - /** - * Similar to previous method, takes a char *, supposed to be in locale 8 bit already. - */ - TDEProcess &operator<<(const char * arg); - /** - * Similar to previous method, takes a TQCString, supposed to be in locale 8 bit already. - * @param arg the argument to add - * @return a reference to this TDEProcess - */ - TDEProcess &operator<<(const TQCString & arg); - - /** - * Sets the executable and the command line argument list for this process, - * in a single method call, or add a list of arguments. - * @param args the arguments to add - * @return a reference to this TDEProcess - **/ - TDEProcess &operator<<(const TQStringList& args); - - /** - * Clear a command line argument list that has been set by using - * operator<<. - */ - void clearArguments(); - - /** - * Starts the process. - * For a detailed description of the - * various run modes and communication semantics, have a look at the - * general description of the TDEProcess class. Note that if you use - * setUsePty( Stdout | Stderr, \<bool\> ), you cannot use Stdout | Stderr - * here - instead, use Stdout only to receive the mixed output. - * - * The following problems could cause this function to - * return false: - * - * @li The process is already running. - * @li The command line argument list is empty. - * @li The the @p comm parameter is incompatible with the selected pty usage. - * @li The starting of the process failed (could not fork). - * @li The executable was not found. - * - * @param runmode The Run-mode for the process. - * @param comm Specifies which communication links should be - * established to the child process (stdin/stdout/stderr). By default, - * no communication takes place and the respective communication - * signals will never get emitted. - * - * @return true on success, false on error - * (see above for error conditions) - **/ - virtual bool start(RunMode runmode = NotifyOnExit, - Communication comm = NoCommunication); - - /** - * Stop the process (by sending it a signal). - * - * @param signo The signal to send. The default is SIGTERM. - * @return true if the signal was delivered successfully. - */ - virtual bool kill(int signo = SIGTERM); - - /** - * Checks whether the process is running. - * @return true if the process is (still) considered to be running - */ - bool isRunning() const; - - /** Returns the process id of the process. - * - * If it is called after - * the process has exited, it returns the process id of the last - * child process that was created by this instance of TDEProcess. - * - * Calling it before any child process has been started by this - * TDEProcess instance causes pid() to return 0. - * @return the pid of the process or 0 if no process has been started yet. - **/ - pid_t pid() const; - - /** - * @deprecated - * Use pid() instead. - */ - TDE_DEPRECATED pid_t getPid() const { return pid(); } - - /** - * Suspend processing of data from stdout of the child process. - */ - void suspend(); - - /** - * Resume processing of data from stdout of the child process. - */ - void resume(); - - /** - * Suspend execution of the current thread until the child process dies - * or the timeout hits. This function is not recommended for programs - * with a GUI. - * @param timeout timeout in seconds. -1 means wait indefinitely. - * @return true if the process exited, false if the timeout hit. - * @since 3.2 - */ - bool wait(int timeout = -1); - - /** - * Checks whether the process exited cleanly. - * - * @return true if the process has already finished and has exited - * "voluntarily", ie: it has not been killed by a signal. - */ - bool normalExit() const; - - /** - * Checks whether the process was killed by a signal. - * - * @return true if the process has already finished and has not exited - * "voluntarily", ie: it has been killed by a signal. - * - * @since 3.2 - */ - bool signalled() const; - - /** - * Checks whether a killed process dumped core. - * - * @return true if signalled() returns true and the process - * dumped core. Note that on systems that don't define the - * WCOREDUMP macro, the return value is always false. - * - * @since 3.2 - */ - bool coreDumped() const; - - /** - * Returns the exit status of the process. - * - * @return the exit status of the process. Note that this value - * is not valid if normalExit() returns false. - */ - int exitStatus() const; - - /** - * Returns the signal the process was killed by. - * - * @return the signal number that caused the process to exit. - * Note that this value is not valid if signalled() returns false. - * - * @since 3.2 - */ - int exitSignal() const; - - /** - * Transmit data to the child process' stdin. - * - * This function may return false in the following cases: - * - * @li The process is not currently running. - * This implies that you cannot use this function in Block mode. - * - * @li Communication to stdin has not been requested in the start() call. - * - * @li Transmission of data to the child process by a previous call to - * 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. - * That means that you must not free @p buffer or call writeStdin() - * again until either a wroteStdin() signal indicates that the - * data has been sent or a processExited() signal shows that - * the child process is no longer alive. - * - * If all the data has been sent to the client, the signal - * wroteStdin() will be emitted. - * - * This function does not work when the process is start()ed in Block mode. - * - * @param buffer the buffer to write - * @param buflen the length of the buffer - * @return false if an error has occurred - **/ - bool writeStdin(const char *buffer, int buflen); - - /** - * Shuts down the Stdin communication link. If no pty is used, this - * causes "EOF" to be indicated on the child's stdin file descriptor. - * - * @return false if no Stdin communication link exists (any more). - */ - bool closeStdin(); - - /** - * Shuts down the Stdout communication link. If no pty is used, any further - * attempts by the child to write to its stdout file descriptor will cause - * it to receive a SIGPIPE. - * - * @return false if no Stdout communication link exists (any more). - */ - bool closeStdout(); - - /** - * Shuts down the Stderr communication link. If no pty is used, any further - * attempts by the child to write to its stderr file descriptor will cause - * it to receive a SIGPIPE. - * - * @return false if no Stderr communication link exists (any more). - */ - bool closeStderr(); - - /** - * Deletes the optional utmp entry and closes the pty. - * - * Make sure to shut down any communication links that are using the pty - * before calling this function. - * - * @return false if the pty is not open (any more). - */ - bool closePty(); - - /** - * @brief Close stdin, stdout, stderr and the pty - * - * This is the same that calling all close* functions in a row: - * @see closeStdin, @see closeStdout, @see closeStderr and @see closePty - */ - void closeAll(); - - /** - * Lets you see what your arguments are for debugging. - * @return the list of arguments - */ - const TQValueList<TQCString> &args() /* const */ { return arguments; } - - /** - * Controls whether the started process should drop any - * setuid/setgid privileges or whether it should keep them. - * Note that this function is mostly a dummy, as the KDE libraries - * currently refuse to run with setuid/setgid privileges. - * - * The default is false: drop privileges - * @param keepPrivileges true to keep the privileges - */ - void setRunPrivileged(bool keepPrivileges); - - /** - * Returns whether the started process will drop any - * setuid/setgid privileges or whether it will keep them. - * @return true if the process runs privileged - */ - bool runPrivileged() const; - - /** - * Adds the variable @p name to the process' environment. - * This function must be called before starting the process. - * @param name the name of the environment variable - * @param value the new value for the environment variable - */ - void setEnvironment(const TQString &name, const TQString &value); - - /** - * Changes the current working directory (CWD) of the process - * to be started. - * This function must be called before starting the process. - * @param dir the new directory - */ - void setWorkingDirectory(const TQString &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, /bin/sh will be used. - * - * When using a shell, the caller should make sure that all filenames etc. - * are properly quoted when passed as argument. - * @see quote() - * @param useShell true if the command should be started via a shell - * @param shell the path to the shell that will execute the process, or - * 0 to use /bin/sh. Use getenv("SHELL") to use the user's - * default shell, but note that doing so is usually a bad idea - * for shell compatibility reasons. - * @since 3.1 - */ - 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. - * @param arg the argument to quote - * @return the quoted argument - * @since 3.1 - */ - static TQString quote(const TQString &arg); - - /** - * Detaches TDEProcess from child process. All communication is closed. - * No exit notification is emitted any more for the child process. - * Deleting the TDEProcess will no longer kill the child process. - * Note that the current process remains the parent process of the - * child process. - */ - void detach(); - -#ifdef Q_OS_UNIX - /** - * Specify whether to create a pty (pseudo-terminal) for running the - * command. - * This function should be called before starting the process. - * - * @param comm for which stdio handles to use a pty. Note that it is not - * allowed to specify Stdout and Stderr at the same time both here and to - * start (there is only one pty, so they cannot be distinguished). - * @param addUtmp true if a utmp entry should be created for the pty - * @since 3.2 - */ - void setUsePty(Communication comm, bool addUtmp); - - /** - * Obtains the pty object used by this process. The return value is - * valid only after setUsePty() was used with a non-zero argument. - * The pty is open only while the process is running. - * @return a pointer to the pty object - * @since 3.2 - */ - KPty *pty() const; -#endif - - /** - * More or less intuitive constants for use with setPriority(). - */ - enum { PrioLowest = 20, PrioLow = 10, PrioLower = 5, PrioNormal = 0, - PrioHigher = -5, PrioHigh = -10, PrioHighest = -19 }; - - /** - * Sets the scheduling priority of the process. - * @param prio the new priority in the range -20 (high) to 19 (low). - * @return false on error; see setpriority(2) for possible reasons. - * @since 3.2 - */ - bool setPriority(int prio); - -signals: - /** - * Emitted after the process has terminated when - * the process was run in the @p NotifyOnExit (==default option to - * start() ) or the Block mode. - * @param proc a pointer to the process that has exited - **/ - void processExited(TDEProcess *proc); - - - /** - * Emitted, when output from the child process has - * been received on stdout. - * - * To actually get this signal, the Stdout communication link - * has to be turned on in start(). - * - * @param proc a pointer to the process that has received the output - * @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 the slot. - * Example: - * \code - * TQString myBuf = TQString::fromLatin1(buffer, buflen); - * \endcode - **/ - void receivedStdout(TDEProcess *proc, char *buffer, int buflen); - - /** - * Emitted when output from the child process has - * been received on stdout. - * - * To actually get this signal, the Stdout communication link - * has to be turned on in start() and the - * NoRead flag must have been passed. - * - * You will need to explicitly call resume() after your call to start() - * to begin processing data from the child process' stdout. This is - * to ensure that this signal is not emitted when no one is connected - * to it, otherwise this signal will not be emitted. - * - * The data still has to be read from file descriptor @p fd. - * @param fd the file descriptor that provides the data - * @param len the number of bytes that have been read from @p fd must - * be written here - **/ - void receivedStdout(int fd, int &len); // KDE4: change, broken API - - - /** - * Emitted, when output from the child process has - * been received on stderr. - * - * To actually get this signal, the Stderr communication link - * has to be turned on in start(). - * - * You should copy the information contained in @p buffer to your private - * data structures before returning from the slot. - * - * @param proc a pointer to the process that has received the data - * @param buffer The data received. - * @param buflen The number of bytes that are available. - **/ - void receivedStderr(TDEProcess *proc, char *buffer, int buflen); - - /** - * Emitted after all the data that has been - * specified by a prior call to writeStdin() has actually been - * written to the child process. - * @param proc a pointer to the process - **/ - void wroteStdin(TDEProcess *proc); - - -protected slots: - - /** - * This slot gets activated when data from the child's stdout arrives. - * It usually calls childOutput(). - * @param fdno the file descriptor for the output - */ - void slotChildOutput(int fdno); - - /** - * This slot gets activated when data from the child's stderr arrives. - * It usually calls childError(). - * @param fdno the file descriptor for the output - */ - void slotChildError(int fdno); - - /** - * Called when another bulk of data can be sent to the child's - * stdin. If there is no more data to be sent to stdin currently - * available, this function must disable the TQSocketNotifier innot. - * @param dummy ignore this argument - */ - void slotSendData(int dummy); // KDE 4: remove dummy - -protected: - - /** - * Sets up the environment according to the data passed via - * setEnvironment() - */ - void setupEnvironment(); - - /** - * The list of the process' command line arguments. The first entry - * in this list is the executable itself. - */ - TQValueList<TQCString> arguments; - /** - * How to run the process (Block, NotifyOnExit, DontCare). You should - * not modify this data member directly from derived classes. - */ - RunMode run_mode; - /** - * true if the process is currently running. You should not - * modify this data member directly from derived classes. Please use - * isRunning() for reading the value of this data member since it - * will probably be made private in later versions of TDEProcess. - */ - bool runs; - - /** - * The PID of the currently running process. - * You should not modify this data member in derived classes. - * Please use pid() instead of directly accessing this - * member since it will probably be made private in - * later versions of TDEProcess. - */ - pid_t pid_; - - /** - * The process' exit status as returned by waitpid(). You should not - * modify the value of this data member from derived classes. You should - * rather use exitStatus() than accessing this data member directly - * since it will probably be made private in further versions of - * TDEProcess. - */ - int status; - - - /** - * If false, the child process' effective uid & gid will be reset to the - * real values. - * @see setRunPrivileged() - */ - bool keepPrivs; - - /** - * This function is called from start() right before a fork() takes - * place. According to the @p comm parameter this function has to initialize - * the in, out and err data members of TDEProcess. - * - * This function should return 1 if setting the needed communication channels - * was successful. - * - * The default implementation is to create UNIX STREAM sockets for the - * communication, but you could reimplement this function to 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 in[0], - * out[1] and out[1]. - * - * Furthermore, it must also create the TQSocketNotifiers innot, - * outnot and errnot and connect their Qt signals to the respective - * TDEProcess slots. - * - * For a more detailed explanation, it is best to have a look at the default - * implementation in kprocess.cpp. - */ - virtual int commSetupDoneP(); - - /** - * Called right after a (successful) fork(), but before an exec() on the child - * process' side. It usually duplicates the in[0], out[1] and - * err[1] file handles to the respective standard I/O handles. - */ - virtual int commSetupDoneC(); - - - /** - * Immediately called after a successfully started process in NotifyOnExit - * mode has exited. This function normally calls commClose() - * and emits the processExited() signal. - * @param state the exit code of the process as returned by waitpid() - */ - virtual void processHasExited(int state); - - /** - * Cleans up the communication links to the child after it has exited. - * This function should act upon the values of pid() and runs. - * See the kprocess.cpp source for details. - * @li If pid() returns zero, the communication links should be closed - * only. - * @li if pid() returns non-zero and runs is false, all data - * immediately available from the communication links should be processed - * before closing them. - * @li if pid() returns non-zero and runs is true, the communication - * links should be monitored for data until the file handle returned by - * TDEProcessController::theTDEProcessController->notifierFd() becomes ready - * for reading - when it triggers, runs should be reset to false, and - * the function should be immediately left without closing anything. - * - * The previous semantics of this function are forward-compatible, but should - * be avoided, as they are prone to race conditions and can cause TDEProcess - * (and thus the whole program) to lock up under certain circumstances. At the - * end the function closes the communication links in any case. Additionally - * @li if runs is true, the communication links are monitored for data - * until all of them have returned EOF. Note that if any system function is - * interrupted (errno == EINTR) the polling loop should be aborted. - * @li if runs is false, all data immediately available from the - * communication links is processed. - */ - virtual void commClose(); - - /* KDE 4 - commClose will be changed to perform cleanup only in all cases * - * If @p notfd is -1, all data immediately available from the - * communication links should be processed. - * If @p notfd is not -1, the communication links should be monitored - * for data until the file handle @p notfd becomes ready for reading. - */ -// virtual void commDrain(int notfd); - - /** - * Specify the actual executable that should be started (first argument to execve) - * Normally the the first argument is the executable but you can - * override that with this function. - */ - void setBinaryExecutable(const char *filename); - - /** - * The socket descriptors for stdout. - */ - int out[2]; - /** - * The socket descriptors for stdin. - */ - int in[2]; - /** - * The socket descriptors for stderr. - */ - int err[2]; - - /** - * The socket notifier for in[1]. - */ - TQSocketNotifier *innot; - /** - * The socket notifier for out[0]. - */ - TQSocketNotifier *outnot; - /** - * The socket notifier for err[0]. - */ - TQSocketNotifier *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' stdout to the respective buffer and emits the signal - * receivedStdout(). - */ - int childOutput(int fdno); - - /** - * Called by slotChildError() this function copies data arriving from - * the child process' stderr to the respective buffer and emits the signal - * receivedStderr(). - */ - int childError(int fdno); - - /** - * The buffer holding the data that has to be sent to the child - */ - const char *input_data; - /** - * The number of bytes already transmitted - */ - int input_sent; - /** - * The total length of input_data - */ - int input_total; - - /** - * TDEProcessController is a friend of TDEProcess because it has to have - * access to various data members. - */ - friend class TDEProcessController; - -protected: - virtual void virtual_hook( int id, void* data ); -private: - TDEProcessPrivate *d; -}; - -class KShellProcessPrivate; - -/** -* @obsolete -* -* Use TDEProcess and TDEProcess::setUseShell(true) instead. -* -* @short A class derived from TDEProcess to start child -* processes through a shell. -* @author Christian Czezatke <e9025461@student.tuwien.ac.at> -*/ -class TDECORE_EXPORT KShellProcess: public TDEProcess -{ - TQ_OBJECT - -public: - - /** - * Constructor - * - * If no shellname is specified, the user's default shell is used. - */ - KShellProcess(const char *shellname=0); - - /** - * Destructor. - */ - ~KShellProcess(); - - virtual bool start(RunMode runmode = NotifyOnExit, - Communication comm = NoCommunication); - - static TQString quote(const TQString &arg); - -private: - TQCString shell; - -protected: - virtual void virtual_hook( int id, void* data ); -private: - KShellProcessPrivate *d; -}; - - - -#endif - +#include <tdeprocess.h> diff --git a/tdecore/kprocio.h b/tdecore/kprocio.h index eda8c6eab..02a3257d5 100644 --- a/tdecore/kprocio.h +++ b/tdecore/kprocio.h @@ -19,7 +19,7 @@ #define KPROCIO_H_ #include <tqstring.h> -#include <kprocess.h> +#include <tdeprocess.h> #include <tqstrlist.h> #include "tdelibs_export.h" diff --git a/tdecore/kpty.cpp b/tdecore/kpty.cpp index a3ff34aec..a66705f4d 100644 --- a/tdecore/kpty.cpp +++ b/tdecore/kpty.cpp @@ -24,7 +24,7 @@ #include <config.h> #include "kpty.h" -#include "kprocess.h" +#include "tdeprocess.h" #ifdef __sgi #define __svr4__ diff --git a/tdecore/ktempdir.cpp b/tdecore/ktempdir.cpp index d16d2e185..a11e582f2 100644 --- a/tdecore/ktempdir.cpp +++ b/tdecore/ktempdir.cpp @@ -52,7 +52,7 @@ #include "kinstance.h" #include "ktempdir.h" #include "kstandarddirs.h" -#include "kprocess.h" +#include "tdeprocess.h" #include <kdebug.h> #include "kde_file.h" diff --git a/tdecore/ktimezones.cpp b/tdecore/ktimezones.cpp index 999446b7c..bf8a370fb 100644 --- a/tdecore/ktimezones.cpp +++ b/tdecore/ktimezones.cpp @@ -22,7 +22,7 @@ #include <ktimezones.h> #include <kdebug.h> #include <kmdcodec.h> -#include <kprocess.h> +#include <tdeprocess.h> #include <kstringhandler.h> #include <tdetempfile.h> diff --git a/tdecore/tdeconfigbackend.cpp b/tdecore/tdeconfigbackend.cpp index a3e8e2c8f..4f83e7716 100644 --- a/tdecore/tdeconfigbackend.cpp +++ b/tdecore/tdeconfigbackend.cpp @@ -43,7 +43,7 @@ #include "tdeconfigbase.h" #include <tdeapplication.h> #include <tdeglobal.h> -#include <kprocess.h> +#include <tdeprocess.h> #include <tdelocale.h> #include <kstandarddirs.h> #include <ksavefile.h> diff --git a/tdecore/kprocess.cpp b/tdecore/tdeprocess.cpp index 85e7620a4..767ddcd2d 100644 --- a/tdecore/kprocess.cpp +++ b/tdecore/tdeprocess.cpp @@ -22,7 +22,7 @@ */ -#include "kprocess.h" +#include "tdeprocess.h" #include "kprocctrl.h" #include "kpty.h" @@ -629,7 +629,7 @@ bool TDEProcess::writeStdin(const char *buffer, int buflen) { // if there is still data pending, writing new data // to stdout is not allowed (since it could also confuse - // kprocess ...) + // tdeprocess ...) if (input_data != 0) return false; @@ -1134,4 +1134,4 @@ bool KShellProcess::start(RunMode runmode, Communication comm) void KShellProcess::virtual_hook( int id, void* data ) { TDEProcess::virtual_hook( id, data ); } -#include "kprocess.moc" +#include "tdeprocess.moc" diff --git a/tdecore/tdeprocess.h b/tdecore/tdeprocess.h new file mode 100644 index 000000000..658571ce7 --- /dev/null +++ b/tdecore/tdeprocess.h @@ -0,0 +1,936 @@ +/* This file is part of the KDE libraries + Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __TDEPROCESS_H__ +#define __TDEPROCESS_H__ + +#include <sys/types.h> // for pid_t +#include <sys/wait.h> +#include <signal.h> +#include <unistd.h> +#include <tqvaluelist.h> +#include <tqcstring.h> +#include <tqobject.h> +#include "tdelibs_export.h" + +class TQSocketNotifier; +class TDEProcessPrivate; + +#ifdef Q_OS_UNIX +#include <kpty.h> +#else +class KPty; +#endif + +/** + * Child process invocation, monitoring and control. + * This class works only in the application's main thread. + * + * <b>General usage and features:</b>\n + * + * This class allows a KDE 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 DontCare -- The child process is invoked and both the child + * process and the parent process continue concurrently. + * + * The process is started in an own session (see setsid(2)). + * + * @li NotifyOnExit -- The child process is invoked and both the + * child and the parent process run concurrently. + * + * When the child process exits, the TDEProcess instance + * corresponding to it emits the Qt signal 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 TDEProcess object gets destructed, the child + * process will be killed if it is still running! + * This means in particular, that it usually makes no sense to use + * a TDEProcess on the stack with NotifyOnExit. + * + * @li OwnGroup -- like NotifyOnExit, but the child process is started + * in an own process group (and an own session, FWIW). The behavior of + * kill() changes to killing the whole process group - this makes + * this mode useful for implementing primitive job management. It can be + * used to work around broken wrapper scripts that don't propagate signals + * to the "real" program. However, use this with care, as you disturb the + * shell's job management if your program is started from the command line. + * + * @li 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.) + * In this mode the parent can read the child's output, but can't send it any + * input. + * + * TDEProcess 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: + * \code + * TDEProcess *proc = new TDEProcess; + * + * *proc << "my_executable"; + * *proc << "These" << "are" << "the" << "command" << "line" << "args"; + * TQApplication::connect(proc, TQ_SIGNAL(processExited(TDEProcess *)), + * pointer_to_my_object, TQ_SLOT(my_objects_slot(TDEProcess *))); + * proc->start(); + * \endcode + * + * This will start "my_executable" with the commandline arguments "These"... + * + * When the child process exits, the slot will be invoked. + * + * <b>Communication with the child process:</b>\n + * + * TDEProcess 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 writeStdin() + * -- Transmit data to the child process' stdin. When all data was sent, the + * signal wroteStdin() is emitted. + * + * @li When data arrives at stdout or stderr, the signal receivedStdout() + * resp. receivedStderr() is emitted. + * + * @li You can shut down individual communication channels with + * closeStdin(), closeStdout(), and closeStderr(), resp. + * + * @author Christian Czezatke e9025461@student.tuwien.ac.at + * + **/ +class TDECORE_EXPORT TDEProcess : public TQObject +{ + TQ_OBJECT + +public: + + /** + * Modes in which the communication channel can be opened. + * + * If communication for more than one channel is required, + * the values have to be or'ed together, for example to get + * communication with stdout as well as with stdin, you would + * specify @p Stdin | @p Stdout + * + * If @p NoRead is specified in conjunction with @p Stdout, + * no data is actually read from @p Stdout but only + * the signal receivedStdout(int fd, int &len) is emitted. + * + * @p CTtyOnly tells setUsePty() to create a PTY for the process + * and make it the process' controlling TTY, but does not redirect + * any I/O channel to the PTY. + * + * If @p MergedStderr is specified in conjunction with @p Stdout, + * Stderr will be redirected onto the same file handle as Stdout, + * i.e., all error output will be signalled with receivedStdout(). + * Don't specify @p Stderr if you specify @p MergedStderr. + */ + enum Communication { + NoCommunication = 0, + Stdin = 1, Stdout = 2, Stderr = 4, + AllOutput = 6, All = 7, + NoRead = 8, + CTtyOnly = NoRead, + MergedStderr = 16 + }; + + /** + * Run-modes for a child process. + */ + enum RunMode { + /** + * The application does not receive notifications from the subprocess when + * it is finished or aborted. + */ + DontCare, + /** + * The application is notified when the subprocess dies. + */ + NotifyOnExit, + /** + * The application is suspended until the started process is finished. + */ + Block, + /** + * Same as NotifyOnExit, but the process is run in an own session, + * just like with DontCare. + */ + OwnGroup + }; + + /** + * Constructor + * @since 3.2 + */ + TDEProcess( TQObject* parent, const char *name = 0 ); + + /** + * Constructor + */ // KDE4 merge with the above + TDEProcess(); + + /** + *Destructor: + * + * If the process is running when the destructor for this class + * is called, the child process is killed with a SIGKILL, but + * only if the run mode is not of type @p DontCare. + * Processes started as @p DontCare keep running anyway. + */ + virtual ~TDEProcess(); + + /** + @deprecated + Use operator<<() instead. + + Sets the executable to be started with this TDEProcess object. + Returns false if the process is currently running (in that + case the executable remains unchanged). + + @see operator<<() + + */ + bool setExecutable(const TQString& proc) TDE_DEPRECATED; + + + /** + * Sets the executable and the command line argument list for this process. + * + * For example, doing an "ls -l /usr/local/bin" can be achieved by: + * \code + * TDEProcess p; + * ... + * p << "ls" << "-l" << "/usr/local/bin" + * \endcode + * + * @param arg the argument to add + * @return a reference to this TDEProcess + **/ + TDEProcess &operator<<(const TQString& arg); + /** + * Similar to previous method, takes a char *, supposed to be in locale 8 bit already. + */ + TDEProcess &operator<<(const char * arg); + /** + * Similar to previous method, takes a TQCString, supposed to be in locale 8 bit already. + * @param arg the argument to add + * @return a reference to this TDEProcess + */ + TDEProcess &operator<<(const TQCString & arg); + + /** + * Sets the executable and the command line argument list for this process, + * in a single method call, or add a list of arguments. + * @param args the arguments to add + * @return a reference to this TDEProcess + **/ + TDEProcess &operator<<(const TQStringList& args); + + /** + * Clear a command line argument list that has been set by using + * operator<<. + */ + void clearArguments(); + + /** + * Starts the process. + * For a detailed description of the + * various run modes and communication semantics, have a look at the + * general description of the TDEProcess class. Note that if you use + * setUsePty( Stdout | Stderr, \<bool\> ), you cannot use Stdout | Stderr + * here - instead, use Stdout only to receive the mixed output. + * + * The following problems could cause this function to + * return false: + * + * @li The process is already running. + * @li The command line argument list is empty. + * @li The the @p comm parameter is incompatible with the selected pty usage. + * @li The starting of the process failed (could not fork). + * @li The executable was not found. + * + * @param runmode The Run-mode for the process. + * @param comm Specifies which communication links should be + * established to the child process (stdin/stdout/stderr). By default, + * no communication takes place and the respective communication + * signals will never get emitted. + * + * @return true on success, false on error + * (see above for error conditions) + **/ + virtual bool start(RunMode runmode = NotifyOnExit, + Communication comm = NoCommunication); + + /** + * Stop the process (by sending it a signal). + * + * @param signo The signal to send. The default is SIGTERM. + * @return true if the signal was delivered successfully. + */ + virtual bool kill(int signo = SIGTERM); + + /** + * Checks whether the process is running. + * @return true if the process is (still) considered to be running + */ + bool isRunning() const; + + /** Returns the process id of the process. + * + * If it is called after + * the process has exited, it returns the process id of the last + * child process that was created by this instance of TDEProcess. + * + * Calling it before any child process has been started by this + * TDEProcess instance causes pid() to return 0. + * @return the pid of the process or 0 if no process has been started yet. + **/ + pid_t pid() const; + + /** + * @deprecated + * Use pid() instead. + */ + TDE_DEPRECATED pid_t getPid() const { return pid(); } + + /** + * Suspend processing of data from stdout of the child process. + */ + void suspend(); + + /** + * Resume processing of data from stdout of the child process. + */ + void resume(); + + /** + * Suspend execution of the current thread until the child process dies + * or the timeout hits. This function is not recommended for programs + * with a GUI. + * @param timeout timeout in seconds. -1 means wait indefinitely. + * @return true if the process exited, false if the timeout hit. + * @since 3.2 + */ + bool wait(int timeout = -1); + + /** + * Checks whether the process exited cleanly. + * + * @return true if the process has already finished and has exited + * "voluntarily", ie: it has not been killed by a signal. + */ + bool normalExit() const; + + /** + * Checks whether the process was killed by a signal. + * + * @return true if the process has already finished and has not exited + * "voluntarily", ie: it has been killed by a signal. + * + * @since 3.2 + */ + bool signalled() const; + + /** + * Checks whether a killed process dumped core. + * + * @return true if signalled() returns true and the process + * dumped core. Note that on systems that don't define the + * WCOREDUMP macro, the return value is always false. + * + * @since 3.2 + */ + bool coreDumped() const; + + /** + * Returns the exit status of the process. + * + * @return the exit status of the process. Note that this value + * is not valid if normalExit() returns false. + */ + int exitStatus() const; + + /** + * Returns the signal the process was killed by. + * + * @return the signal number that caused the process to exit. + * Note that this value is not valid if signalled() returns false. + * + * @since 3.2 + */ + int exitSignal() const; + + /** + * Transmit data to the child process' stdin. + * + * This function may return false in the following cases: + * + * @li The process is not currently running. + * This implies that you cannot use this function in Block mode. + * + * @li Communication to stdin has not been requested in the start() call. + * + * @li Transmission of data to the child process by a previous call to + * 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. + * That means that you must not free @p buffer or call writeStdin() + * again until either a wroteStdin() signal indicates that the + * data has been sent or a processExited() signal shows that + * the child process is no longer alive. + * + * If all the data has been sent to the client, the signal + * wroteStdin() will be emitted. + * + * This function does not work when the process is start()ed in Block mode. + * + * @param buffer the buffer to write + * @param buflen the length of the buffer + * @return false if an error has occurred + **/ + bool writeStdin(const char *buffer, int buflen); + + /** + * Shuts down the Stdin communication link. If no pty is used, this + * causes "EOF" to be indicated on the child's stdin file descriptor. + * + * @return false if no Stdin communication link exists (any more). + */ + bool closeStdin(); + + /** + * Shuts down the Stdout communication link. If no pty is used, any further + * attempts by the child to write to its stdout file descriptor will cause + * it to receive a SIGPIPE. + * + * @return false if no Stdout communication link exists (any more). + */ + bool closeStdout(); + + /** + * Shuts down the Stderr communication link. If no pty is used, any further + * attempts by the child to write to its stderr file descriptor will cause + * it to receive a SIGPIPE. + * + * @return false if no Stderr communication link exists (any more). + */ + bool closeStderr(); + + /** + * Deletes the optional utmp entry and closes the pty. + * + * Make sure to shut down any communication links that are using the pty + * before calling this function. + * + * @return false if the pty is not open (any more). + */ + bool closePty(); + + /** + * @brief Close stdin, stdout, stderr and the pty + * + * This is the same that calling all close* functions in a row: + * @see closeStdin, @see closeStdout, @see closeStderr and @see closePty + */ + void closeAll(); + + /** + * Lets you see what your arguments are for debugging. + * @return the list of arguments + */ + const TQValueList<TQCString> &args() /* const */ { return arguments; } + + /** + * Controls whether the started process should drop any + * setuid/setgid privileges or whether it should keep them. + * Note that this function is mostly a dummy, as the KDE libraries + * currently refuse to run with setuid/setgid privileges. + * + * The default is false: drop privileges + * @param keepPrivileges true to keep the privileges + */ + void setRunPrivileged(bool keepPrivileges); + + /** + * Returns whether the started process will drop any + * setuid/setgid privileges or whether it will keep them. + * @return true if the process runs privileged + */ + bool runPrivileged() const; + + /** + * Adds the variable @p name to the process' environment. + * This function must be called before starting the process. + * @param name the name of the environment variable + * @param value the new value for the environment variable + */ + void setEnvironment(const TQString &name, const TQString &value); + + /** + * Changes the current working directory (CWD) of the process + * to be started. + * This function must be called before starting the process. + * @param dir the new directory + */ + void setWorkingDirectory(const TQString &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, /bin/sh will be used. + * + * When using a shell, the caller should make sure that all filenames etc. + * are properly quoted when passed as argument. + * @see quote() + * @param useShell true if the command should be started via a shell + * @param shell the path to the shell that will execute the process, or + * 0 to use /bin/sh. Use getenv("SHELL") to use the user's + * default shell, but note that doing so is usually a bad idea + * for shell compatibility reasons. + * @since 3.1 + */ + 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. + * @param arg the argument to quote + * @return the quoted argument + * @since 3.1 + */ + static TQString quote(const TQString &arg); + + /** + * Detaches TDEProcess from child process. All communication is closed. + * No exit notification is emitted any more for the child process. + * Deleting the TDEProcess will no longer kill the child process. + * Note that the current process remains the parent process of the + * child process. + */ + void detach(); + +#ifdef Q_OS_UNIX + /** + * Specify whether to create a pty (pseudo-terminal) for running the + * command. + * This function should be called before starting the process. + * + * @param comm for which stdio handles to use a pty. Note that it is not + * allowed to specify Stdout and Stderr at the same time both here and to + * start (there is only one pty, so they cannot be distinguished). + * @param addUtmp true if a utmp entry should be created for the pty + * @since 3.2 + */ + void setUsePty(Communication comm, bool addUtmp); + + /** + * Obtains the pty object used by this process. The return value is + * valid only after setUsePty() was used with a non-zero argument. + * The pty is open only while the process is running. + * @return a pointer to the pty object + * @since 3.2 + */ + KPty *pty() const; +#endif + + /** + * More or less intuitive constants for use with setPriority(). + */ + enum { PrioLowest = 20, PrioLow = 10, PrioLower = 5, PrioNormal = 0, + PrioHigher = -5, PrioHigh = -10, PrioHighest = -19 }; + + /** + * Sets the scheduling priority of the process. + * @param prio the new priority in the range -20 (high) to 19 (low). + * @return false on error; see setpriority(2) for possible reasons. + * @since 3.2 + */ + bool setPriority(int prio); + +signals: + /** + * Emitted after the process has terminated when + * the process was run in the @p NotifyOnExit (==default option to + * start() ) or the Block mode. + * @param proc a pointer to the process that has exited + **/ + void processExited(TDEProcess *proc); + + + /** + * Emitted, when output from the child process has + * been received on stdout. + * + * To actually get this signal, the Stdout communication link + * has to be turned on in start(). + * + * @param proc a pointer to the process that has received the output + * @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 the slot. + * Example: + * \code + * TQString myBuf = TQString::fromLatin1(buffer, buflen); + * \endcode + **/ + void receivedStdout(TDEProcess *proc, char *buffer, int buflen); + + /** + * Emitted when output from the child process has + * been received on stdout. + * + * To actually get this signal, the Stdout communication link + * has to be turned on in start() and the + * NoRead flag must have been passed. + * + * You will need to explicitly call resume() after your call to start() + * to begin processing data from the child process' stdout. This is + * to ensure that this signal is not emitted when no one is connected + * to it, otherwise this signal will not be emitted. + * + * The data still has to be read from file descriptor @p fd. + * @param fd the file descriptor that provides the data + * @param len the number of bytes that have been read from @p fd must + * be written here + **/ + void receivedStdout(int fd, int &len); // KDE4: change, broken API + + + /** + * Emitted, when output from the child process has + * been received on stderr. + * + * To actually get this signal, the Stderr communication link + * has to be turned on in start(). + * + * You should copy the information contained in @p buffer to your private + * data structures before returning from the slot. + * + * @param proc a pointer to the process that has received the data + * @param buffer The data received. + * @param buflen The number of bytes that are available. + **/ + void receivedStderr(TDEProcess *proc, char *buffer, int buflen); + + /** + * Emitted after all the data that has been + * specified by a prior call to writeStdin() has actually been + * written to the child process. + * @param proc a pointer to the process + **/ + void wroteStdin(TDEProcess *proc); + + +protected slots: + + /** + * This slot gets activated when data from the child's stdout arrives. + * It usually calls childOutput(). + * @param fdno the file descriptor for the output + */ + void slotChildOutput(int fdno); + + /** + * This slot gets activated when data from the child's stderr arrives. + * It usually calls childError(). + * @param fdno the file descriptor for the output + */ + void slotChildError(int fdno); + + /** + * Called when another bulk of data can be sent to the child's + * stdin. If there is no more data to be sent to stdin currently + * available, this function must disable the TQSocketNotifier innot. + * @param dummy ignore this argument + */ + void slotSendData(int dummy); // KDE 4: remove dummy + +protected: + + /** + * Sets up the environment according to the data passed via + * setEnvironment() + */ + void setupEnvironment(); + + /** + * The list of the process' command line arguments. The first entry + * in this list is the executable itself. + */ + TQValueList<TQCString> arguments; + /** + * How to run the process (Block, NotifyOnExit, DontCare). You should + * not modify this data member directly from derived classes. + */ + RunMode run_mode; + /** + * true if the process is currently running. You should not + * modify this data member directly from derived classes. Please use + * isRunning() for reading the value of this data member since it + * will probably be made private in later versions of TDEProcess. + */ + bool runs; + + /** + * The PID of the currently running process. + * You should not modify this data member in derived classes. + * Please use pid() instead of directly accessing this + * member since it will probably be made private in + * later versions of TDEProcess. + */ + pid_t pid_; + + /** + * The process' exit status as returned by waitpid(). You should not + * modify the value of this data member from derived classes. You should + * rather use exitStatus() than accessing this data member directly + * since it will probably be made private in further versions of + * TDEProcess. + */ + int status; + + + /** + * If false, the child process' effective uid & gid will be reset to the + * real values. + * @see setRunPrivileged() + */ + bool keepPrivs; + + /** + * This function is called from start() right before a fork() takes + * place. According to the @p comm parameter this function has to initialize + * the in, out and err data members of TDEProcess. + * + * This function should return 1 if setting the needed communication channels + * was successful. + * + * The default implementation is to create UNIX STREAM sockets for the + * communication, but you could reimplement this function to 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 in[0], + * out[1] and out[1]. + * + * Furthermore, it must also create the TQSocketNotifiers innot, + * outnot and errnot and connect their Qt signals to the respective + * TDEProcess slots. + * + * For a more detailed explanation, it is best to have a look at the default + * implementation in tdeprocess.cpp. + */ + virtual int commSetupDoneP(); + + /** + * Called right after a (successful) fork(), but before an exec() on the child + * process' side. It usually duplicates the in[0], out[1] and + * err[1] file handles to the respective standard I/O handles. + */ + virtual int commSetupDoneC(); + + + /** + * Immediately called after a successfully started process in NotifyOnExit + * mode has exited. This function normally calls commClose() + * and emits the processExited() signal. + * @param state the exit code of the process as returned by waitpid() + */ + virtual void processHasExited(int state); + + /** + * Cleans up the communication links to the child after it has exited. + * This function should act upon the values of pid() and runs. + * See the tdeprocess.cpp source for details. + * @li If pid() returns zero, the communication links should be closed + * only. + * @li if pid() returns non-zero and runs is false, all data + * immediately available from the communication links should be processed + * before closing them. + * @li if pid() returns non-zero and runs is true, the communication + * links should be monitored for data until the file handle returned by + * TDEProcessController::theTDEProcessController->notifierFd() becomes ready + * for reading - when it triggers, runs should be reset to false, and + * the function should be immediately left without closing anything. + * + * The previous semantics of this function are forward-compatible, but should + * be avoided, as they are prone to race conditions and can cause TDEProcess + * (and thus the whole program) to lock up under certain circumstances. At the + * end the function closes the communication links in any case. Additionally + * @li if runs is true, the communication links are monitored for data + * until all of them have returned EOF. Note that if any system function is + * interrupted (errno == EINTR) the polling loop should be aborted. + * @li if runs is false, all data immediately available from the + * communication links is processed. + */ + virtual void commClose(); + + /* KDE 4 - commClose will be changed to perform cleanup only in all cases * + * If @p notfd is -1, all data immediately available from the + * communication links should be processed. + * If @p notfd is not -1, the communication links should be monitored + * for data until the file handle @p notfd becomes ready for reading. + */ +// virtual void commDrain(int notfd); + + /** + * Specify the actual executable that should be started (first argument to execve) + * Normally the the first argument is the executable but you can + * override that with this function. + */ + void setBinaryExecutable(const char *filename); + + /** + * The socket descriptors for stdout. + */ + int out[2]; + /** + * The socket descriptors for stdin. + */ + int in[2]; + /** + * The socket descriptors for stderr. + */ + int err[2]; + + /** + * The socket notifier for in[1]. + */ + TQSocketNotifier *innot; + /** + * The socket notifier for out[0]. + */ + TQSocketNotifier *outnot; + /** + * The socket notifier for err[0]. + */ + TQSocketNotifier *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' stdout to the respective buffer and emits the signal + * receivedStdout(). + */ + int childOutput(int fdno); + + /** + * Called by slotChildError() this function copies data arriving from + * the child process' stderr to the respective buffer and emits the signal + * receivedStderr(). + */ + int childError(int fdno); + + /** + * The buffer holding the data that has to be sent to the child + */ + const char *input_data; + /** + * The number of bytes already transmitted + */ + int input_sent; + /** + * The total length of input_data + */ + int input_total; + + /** + * TDEProcessController is a friend of TDEProcess because it has to have + * access to various data members. + */ + friend class TDEProcessController; + +protected: + virtual void virtual_hook( int id, void* data ); +private: + TDEProcessPrivate *d; +}; + +class KShellProcessPrivate; + +/** +* @obsolete +* +* Use TDEProcess and TDEProcess::setUseShell(true) instead. +* +* @short A class derived from TDEProcess to start child +* processes through a shell. +* @author Christian Czezatke <e9025461@student.tuwien.ac.at> +*/ +class TDECORE_EXPORT KShellProcess: public TDEProcess +{ + TQ_OBJECT + +public: + + /** + * Constructor + * + * If no shellname is specified, the user's default shell is used. + */ + KShellProcess(const char *shellname=0); + + /** + * Destructor. + */ + ~KShellProcess(); + + virtual bool start(RunMode runmode = NotifyOnExit, + Communication comm = NoCommunication); + + static TQString quote(const TQString &arg); + +private: + TQCString shell; + +protected: + virtual void virtual_hook( int id, void* data ); +private: + KShellProcessPrivate *d; +}; + +#endif diff --git a/tdecore/tdesycoca.cpp b/tdecore/tdesycoca.cpp index b39ca239e..b1b150df7 100644 --- a/tdecore/tdesycoca.cpp +++ b/tdecore/tdesycoca.cpp @@ -30,7 +30,7 @@ #include <dcopclient.h> #include <tdeglobal.h> #include <kdebug.h> -#include <kprocess.h> +#include <tdeprocess.h> #include <kstandarddirs.h> #include <assert.h> diff --git a/tdecore/tests/CMakeLists.txt b/tdecore/tests/CMakeLists.txt index f3e0aae45..fa14f6357 100644 --- a/tdecore/tests/CMakeLists.txt +++ b/tdecore/tests/CMakeLists.txt @@ -31,7 +31,7 @@ tde_add_library( tdeconfigtest SHARED AUTOMOC ) set( CHECKS - tdeconfigtestgui klocaletest kprocesstest ksimpleconfigtest kstddirstest + tdeconfigtestgui klocaletest tdeprocesstest ksimpleconfigtest kstddirstest tdeuniqueapptest ktempfiletest krandomsequencetest kdebugtest ksocktest kstringhandlertest kcmdlineargstest kapptest kmemtest dcopkonqtest kipctest cplusplustest kiconloadertest kresolvertest diff --git a/tdecore/tests/Makefile.am b/tdecore/tests/Makefile.am index 9398716eb..19787c4df 100644 --- a/tdecore/tests/Makefile.am +++ b/tdecore/tests/Makefile.am @@ -21,7 +21,7 @@ INCLUDES = -I$(top_srcdir)/tdecore $(all_includes) AM_LDFLAGS = $(QT_LDFLAGS) $(X_LDFLAGS) $(KDE_RPATH) -check_PROGRAMS = tdeconfigtestgui klocaletest kprocesstest ksimpleconfigtest \ +check_PROGRAMS = tdeconfigtestgui klocaletest tdeprocesstest ksimpleconfigtest \ kstddirstest kurltest tdeuniqueapptest ktempfiletest krandomsequencetest \ kdebugtest ksocktest kstringhandlertest kcmdlineargstest kapptest \ kmemtest kidlservertest kidlclienttest dcopkonqtest kipctest \ @@ -32,7 +32,7 @@ check_PROGRAMS = tdeconfigtestgui klocaletest kprocesstest ksimpleconfigtest \ TESTS = kurltest tdestdacceltest -noinst_HEADERS = klocaletest.h kprocesstest.h KIDLTest.h \ +noinst_HEADERS = klocaletest.h tdeprocesstest.h KIDLTest.h \ kipctest.h kprociotest.h METASOURCES = AUTO @@ -46,7 +46,7 @@ klocaletest_SOURCES = klocaletest.cpp ksimpleconfigtest_SOURCES = ksimpleconfigtest.cpp kurltest_SOURCES = kurltest.cpp kstddirstest_SOURCES = kstddirstest.cpp -kprocesstest_SOURCES = kprocesstest.cpp +tdeprocesstest_SOURCES = tdeprocesstest.cpp tdeuniqueapptest_SOURCES = tdeuniqueapptest.cpp kapptest_SOURCES = kapptest.cpp ksocktest_SOURCES = ksocktest.cpp diff --git a/tdecore/tests/kprociotest.cpp b/tdecore/tests/kprociotest.cpp index e7165092c..81522f394 100644 --- a/tdecore/tests/kprociotest.cpp +++ b/tdecore/tests/kprociotest.cpp @@ -9,7 +9,7 @@ // -#include "kprocess.h" +#include "tdeprocess.h" #include <stdio.h> #include <string.h> diff --git a/tdecore/tests/kprocesstest.cpp b/tdecore/tests/tdeprocesstest.cpp index b7908ec6e..0d27f69fa 100644 --- a/tdecore/tests/kprocesstest.cpp +++ b/tdecore/tests/tdeprocesstest.cpp @@ -9,7 +9,7 @@ // -#include "kprocess.h" +#include "tdeprocess.h" #include <stdio.h> #include <string.h> @@ -17,7 +17,7 @@ #include <signal.h> -#include "kprocesstest.h" +#include "tdeprocesstest.h" #define PROCNO 10 @@ -34,7 +34,7 @@ int main(int argc, char *argv[]) { TDEProcess p1, p2, p3, p4; Dummy dummy; - TDEApplication app(argc, argv, TQCString("kprocesstest")); + TDEApplication app(argc, argv, TQCString("tdeprocesstest")); printf("Welcome to the TDEProcess Demo Application!\n"); @@ -113,4 +113,4 @@ int main(int argc, char *argv[]) return 0; } -#include "kprocesstest.moc" +#include "tdeprocesstest.moc" diff --git a/tdecore/tests/kprocesstest.h b/tdecore/tests/tdeprocesstest.h index 4bd4ab71e..32a559157 100644 --- a/tdecore/tests/kprocesstest.h +++ b/tdecore/tests/tdeprocesstest.h @@ -13,7 +13,7 @@ #include <stdio.h> #include <tqobject.h> -#include "kprocess.h" +#include "tdeprocess.h" class Dummy : public TQObject { @@ -46,5 +46,3 @@ class Dummy : public TQObject }; #endif - - |