File indexing completed on 2024-05-12 04:51:18

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 K3B_KPROCESS_H
0010 #define K3B_KPROCESS_H
0011 
0012 #include "k3bqprocess.h"
0013 #include "k3b_export.h"
0014 #include <KProcess>
0015 
0016 class K3bKProcessPrivate;
0017 
0018 /**
0019  * \class K3bKProcess KCoreAddons/KProcess <K3bKProcess>
0020  *
0021  * Child process invocation, monitoring and control.
0022  *
0023  * This class extends QProcess by some useful functionality, overrides
0024  * some defaults with saner values and wraps parts of the API into a more
0025  * accessible one.
0026  * This is the preferred way of spawning child processes in KDE; don't
0027  * use QProcess directly.
0028  *
0029  * @author Oswald Buddenhagen <ossi@kde.org>
0030  **/
0031 class LIBK3B_EXPORT K3bKProcess : public K3bQProcess
0032 {
0033     Q_OBJECT
0034     Q_DECLARE_PRIVATE(K3bKProcess)
0035 
0036 public:
0037     // we reuse the KProcess enum to make future transition easier
0038 #if 0
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 K3bKProcess
0045                  as separate channels */
0046         MergedChannels = ::QProcess::MergedChannels,
0047             /**< Standard output and standard error are handled by K3bKProcess
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,
0053             /**< Only standard output is handled; standard error is forwarded */
0054         OnlyStderrChannel  /**< Only standard error is handled; standard output is forwarded */
0055     };
0056 #endif
0057 
0058     /**
0059      * Constructor
0060      */
0061     explicit K3bKProcess(QObject *parent = 0);
0062 
0063     /**
0064      * Destructor
0065      */
0066     ~K3bKProcess() 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(KProcess::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     KProcess::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      *  K3bKProcess 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 K3bKProcess
0165      */
0166     K3bKProcess &operator<<(const QString& arg);
0167 
0168     /**
0169      * @overload
0170      *
0171      * @param args the arguments to add
0172      * @return a reference to this K3bKProcess
0173      */
0174     K3bKProcess &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 K3bKProcess determines that the command does not really need a
0191      * shell, it will trasparently 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      * </code>
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 K3bKProcess 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     /**
0296      * Obtain the process' ID as known to the system.
0297      *
0298      * Unlike with QProcess::pid(), this is a real PID also on Windows.
0299      *
0300      * This function can be called only while the process is running.
0301      * It cannot be applied to detached processes.
0302      *
0303      * @return the process ID
0304      */
0305     int pid() const;
0306 
0307 protected:
0308     /**
0309      * @internal
0310      */
0311     K3bKProcess(K3bKProcessPrivate *d, QObject *parent);
0312 
0313     /**
0314      * @internal
0315      */
0316     K3bKProcessPrivate * const d_ptr;
0317 
0318 private:
0319     // hide those
0320     using K3bQProcess::setReadChannelMode;
0321     using K3bQProcess::readChannelMode;
0322     using K3bQProcess::setProcessChannelMode;
0323     using K3bQProcess::processChannelMode;
0324 
0325     Q_PRIVATE_SLOT(d_func(), void _k_forwardStdout())
0326     Q_PRIVATE_SLOT(d_func(), void _k_forwardStderr())
0327 };
0328 
0329 #endif
0330