File indexing completed on 2024-05-12 03:54:56

0001 /*
0002     This file is part of the KDE libraries
0003 
0004     SPDX-FileCopyrightText: 2007 Oswald Buddenhagen <ossi@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #ifndef KPROCESS_H
0010 #define KPROCESS_H
0011 
0012 #include <kcoreaddons_export.h>
0013 
0014 #include <QProcess>
0015 
0016 #include <memory>
0017 
0018 class KProcessPrivate;
0019 
0020 /**
0021  * \class KProcess kprocess.h <KProcess>
0022  *
0023  * Child process invocation, monitoring and control.
0024  *
0025  * This class extends QProcess by some useful functionality, overrides
0026  * some defaults with saner values and wraps parts of the API into a more
0027  * accessible one.
0028  * Only use KProcess if you need the extra features, otherwise QProcess
0029  * is the preferred way of spawning child processes.
0030  *
0031  * @author Oswald Buddenhagen <ossi@kde.org>
0032  **/
0033 class KCOREADDONS_EXPORT KProcess : public QProcess
0034 {
0035     Q_OBJECT
0036     Q_DECLARE_PRIVATE(KProcess)
0037 
0038 public:
0039     /**
0040      * Modes in which the output channels can be opened.
0041      */
0042     enum OutputChannelMode {
0043         SeparateChannels = QProcess::SeparateChannels,
0044         /**< Standard output and standard error are handled by KProcess
0045              as separate channels */
0046         MergedChannels = QProcess::MergedChannels,
0047         /**< Standard output and standard error are handled by KProcess
0048              as one channel */
0049         ForwardedChannels = QProcess::ForwardedChannels,
0050         /**< Both standard output and standard error are forwarded
0051              to the parent process' respective channel */
0052         OnlyStdoutChannel = QProcess::ForwardedErrorChannel,
0053         /**< Only standard output is handled; standard error is forwarded */
0054         OnlyStderrChannel = QProcess::ForwardedOutputChannel,
0055         /**< Only standard error is handled; standard output is forwarded */
0056     };
0057 
0058     /**
0059      * Constructor
0060      */
0061     explicit KProcess(QObject *parent = nullptr);
0062 
0063     /**
0064      * Destructor
0065      */
0066     ~KProcess() override;
0067 
0068     /**
0069      * Set how to handle the output channels of the child process.
0070      *
0071      * The default is ForwardedChannels, which is unlike in QProcess.
0072      * Do not request more than you actually handle, as this output is
0073      * simply lost otherwise.
0074      *
0075      * This function must be called before starting the process.
0076      *
0077      * @param mode the output channel handling mode
0078      */
0079     void setOutputChannelMode(OutputChannelMode mode);
0080 
0081     /**
0082      * Query how the output channels of the child process are handled.
0083      *
0084      * @return the output channel handling mode
0085      */
0086     OutputChannelMode outputChannelMode() const;
0087 
0088     /**
0089      * Set the QIODevice open mode the process will be opened in.
0090      *
0091      * This function must be called before starting the process, obviously.
0092      *
0093      * @param mode the open mode. Note that this mode is automatically
0094      *   "reduced" according to the channel modes and redirections.
0095      *   The default is QIODevice::ReadWrite.
0096      */
0097     void setNextOpenMode(QIODevice::OpenMode mode);
0098 
0099     /**
0100      * Adds the variable @p name to the process' environment.
0101      *
0102      * This function must be called before starting the process.
0103      *
0104      * @param name the name of the environment variable
0105      * @param value the new value for the environment variable
0106      * @param overwrite if @c false and the environment variable is already
0107      *   set, the old value will be preserved
0108      */
0109     void setEnv(const QString &name, const QString &value, bool overwrite = true);
0110 
0111     /**
0112      * Removes the variable @p name from the process' environment.
0113      *
0114      * This function must be called before starting the process.
0115      *
0116      * @param name the name of the environment variable
0117      */
0118     void unsetEnv(const QString &name);
0119 
0120     /**
0121      * Empties the process' environment.
0122      *
0123      * Note that LD_LIBRARY_PATH/DYLD_LIBRARY_PATH is automatically added
0124      * on *NIX.
0125      *
0126      * This function must be called before starting the process.
0127      */
0128     void clearEnvironment();
0129 
0130     /**
0131      * Set the program and the command line arguments.
0132      *
0133      * This function must be called before starting the process, obviously.
0134      *
0135      * @param exe the program to execute
0136      * @param args the command line arguments for the program,
0137      *   one per list element
0138      */
0139     void setProgram(const QString &exe, const QStringList &args = QStringList());
0140 
0141     /**
0142      * @overload
0143      *
0144      * @param argv the program to execute and the command line arguments
0145      *   for the program, one per list element
0146      */
0147     void setProgram(const QStringList &argv);
0148 
0149     /**
0150      * Append an element to the command line argument list for this process.
0151      *
0152      * If no executable is set yet, it will be set instead.
0153      *
0154      * For example, doing an "ls -l /usr/local/bin" can be achieved by:
0155      *  \code
0156      *  KProcess p;
0157      *  p << "ls" << "-l" << "/usr/local/bin";
0158      *  ...
0159      *  \endcode
0160      *
0161      * This function must be called before starting the process, obviously.
0162      *
0163      * @param arg the argument to add
0164      * @return a reference to this KProcess
0165      */
0166     KProcess &operator<<(const QString &arg);
0167 
0168     /**
0169      * @overload
0170      *
0171      * @param args the arguments to add
0172      * @return a reference to this KProcess
0173      */
0174     KProcess &operator<<(const QStringList &args);
0175 
0176     /**
0177      * Clear the program and command line argument list.
0178      */
0179     void clearProgram();
0180 
0181     /**
0182      * Set a command to execute through a shell (a POSIX sh on *NIX
0183      * and cmd.exe on Windows).
0184      *
0185      * Using this for anything but user-supplied commands is usually a bad
0186      * idea, as the command's syntax depends on the platform.
0187      * Redirections including pipes, etc. are better handled by the
0188      * respective functions provided by QProcess.
0189      *
0190      * If KProcess determines that the command does not really need a
0191      * shell, it will transparently execute it without one for performance
0192      * reasons.
0193      *
0194      * This function must be called before starting the process, obviously.
0195      *
0196      * @param cmd the command to execute through a shell.
0197      *   The caller must make sure that all filenames etc. are properly
0198      *   quoted when passed as argument. Failure to do so often results in
0199      *   serious security holes. See KShell::quoteArg().
0200      */
0201     void setShellCommand(const QString &cmd);
0202 
0203     /**
0204      * Obtain the currently set program and arguments.
0205      *
0206      * @return a list, the first element being the program, the remaining ones
0207      *  being command line arguments to the program.
0208      */
0209     QStringList program() const;
0210 
0211     /**
0212      * Start the process.
0213      *
0214      * @see QProcess::start(const QString &, const QStringList &, OpenMode)
0215      */
0216     void start();
0217 
0218     /**
0219      * Start the process, wait for it to finish, and return the exit code.
0220      *
0221      * This method is roughly equivalent to the sequence:
0222      * @code
0223      *   start();
0224      *   waitForFinished(msecs);
0225      *   return exitCode();
0226      * @endcode
0227      *
0228      * Unlike the other execute() variants this method is not static,
0229      * so the process can be parametrized properly and talked to.
0230      *
0231      * @param msecs time to wait for process to exit before killing it
0232      * @return -2 if the process could not be started, -1 if it crashed,
0233      *  otherwise its exit code
0234      */
0235     int execute(int msecs = -1);
0236 
0237     /**
0238      * @overload
0239      *
0240      * @param exe the program to execute
0241      * @param args the command line arguments for the program,
0242      *   one per list element
0243      * @param msecs time to wait for process to exit before killing it
0244      * @return -2 if the process could not be started, -1 if it crashed,
0245      *  otherwise its exit code
0246      */
0247     static int execute(const QString &exe, const QStringList &args = QStringList(), int msecs = -1);
0248 
0249     /**
0250      * @overload
0251      *
0252      * @param argv the program to execute and the command line arguments
0253      *   for the program, one per list element
0254      * @param msecs time to wait for process to exit before killing it
0255      * @return -2 if the process could not be started, -1 if it crashed,
0256      *  otherwise its exit code
0257      */
0258     static int execute(const QStringList &argv, int msecs = -1);
0259 
0260     /**
0261      * Start the process and detach from it. See QProcess::startDetached()
0262      * for details.
0263      *
0264      * Unlike the other startDetached() variants this method is not static,
0265      * so the process can be parametrized properly.
0266      * @note Currently, only the setProgram()/setShellCommand() and
0267      * setWorkingDirectory() parametrizations are supported.
0268      *
0269      * The KProcess object may be re-used immediately after calling this
0270      * function.
0271      *
0272      * @return the PID of the started process or 0 on error
0273      */
0274     int startDetached();
0275 
0276     /**
0277      * @overload
0278      *
0279      * @param exe the program to start
0280      * @param args the command line arguments for the program,
0281      *   one per list element
0282      * @return the PID of the started process or 0 on error
0283      */
0284     static int startDetached(const QString &exe, const QStringList &args = QStringList());
0285 
0286     /**
0287      * @overload
0288      *
0289      * @param argv the program to start and the command line arguments
0290      *   for the program, one per list element
0291      * @return the PID of the started process or 0 on error
0292      */
0293     static int startDetached(const QStringList &argv);
0294 
0295 protected:
0296     /**
0297      * @internal
0298      */
0299     KCOREADDONS_NO_EXPORT KProcess(KProcessPrivate *d, QObject *parent);
0300 
0301     /**
0302      * @internal
0303      */
0304     std::unique_ptr<KProcessPrivate> const d_ptr;
0305 
0306 private:
0307     // hide those
0308     using QProcess::processChannelMode;
0309     using QProcess::setProcessChannelMode;
0310 };
0311 
0312 #endif