1 /* 2 This file is part of the KDE libraries 3 4 SPDX-FileCopyrightText: 2007 Oswald Buddenhagen <ossi@kde.org> 5 6 SPDX-License-Identifier: LGPL-2.0-or-later 7 */ 8 9 #ifndef KPROCESS_H 10 #define KPROCESS_H 11 12 #include <kcoreaddons_export.h> 13 14 #include <QProcess> 15 16 #include <memory> 17 18 class KProcessPrivate; 19 20 /** 21 * \class KProcess kprocess.h <KProcess> 22 * 23 * Child process invocation, monitoring and control. 24 * 25 * This class extends QProcess by some useful functionality, overrides 26 * some defaults with saner values and wraps parts of the API into a more 27 * accessible one. 28 * Only use KProcess if you need the extra features, otherwise QProcess 29 * is the preferred way of spawning child processes. 30 * 31 * @author Oswald Buddenhagen <ossi@kde.org> 32 **/ 33 class KCOREADDONS_EXPORT KProcess : public QProcess 34 { 35 Q_OBJECT 36 Q_DECLARE_PRIVATE(KProcess) 37 38 public: 39 /** 40 * Modes in which the output channels can be opened. 41 */ 42 enum OutputChannelMode { 43 SeparateChannels = QProcess::SeparateChannels, 44 /**< Standard output and standard error are handled by KProcess 45 as separate channels */ 46 MergedChannels = QProcess::MergedChannels, 47 /**< Standard output and standard error are handled by KProcess 48 as one channel */ 49 ForwardedChannels = QProcess::ForwardedChannels, 50 /**< Both standard output and standard error are forwarded 51 to the parent process' respective channel */ 52 OnlyStdoutChannel = QProcess::ForwardedErrorChannel, 53 /**< Only standard output is handled; standard error is forwarded */ 54 OnlyStderrChannel = QProcess::ForwardedOutputChannel, 55 /**< Only standard error is handled; standard output is forwarded */ 56 }; 57 58 /** 59 * Constructor 60 */ 61 explicit KProcess(QObject *parent = nullptr); 62 63 /** 64 * Destructor 65 */ 66 ~KProcess() override; 67 68 /** 69 * Set how to handle the output channels of the child process. 70 * 71 * The default is ForwardedChannels, which is unlike in QProcess. 72 * Do not request more than you actually handle, as this output is 73 * simply lost otherwise. 74 * 75 * This function must be called before starting the process. 76 * 77 * @param mode the output channel handling mode 78 */ 79 void setOutputChannelMode(OutputChannelMode mode); 80 81 /** 82 * Query how the output channels of the child process are handled. 83 * 84 * @return the output channel handling mode 85 */ 86 OutputChannelMode outputChannelMode() const; 87 88 /** 89 * Set the QIODevice open mode the process will be opened in. 90 * 91 * This function must be called before starting the process, obviously. 92 * 93 * @param mode the open mode. Note that this mode is automatically 94 * "reduced" according to the channel modes and redirections. 95 * The default is QIODevice::ReadWrite. 96 */ 97 void setNextOpenMode(QIODevice::OpenMode mode); 98 99 /** 100 * Adds the variable @p name to the process' environment. 101 * 102 * This function must be called before starting the process. 103 * 104 * @param name the name of the environment variable 105 * @param value the new value for the environment variable 106 * @param overwrite if @c false and the environment variable is already 107 * set, the old value will be preserved 108 */ 109 void setEnv(const QString &name, const QString &value, bool overwrite = true); 110 111 /** 112 * Removes the variable @p name from the process' environment. 113 * 114 * This function must be called before starting the process. 115 * 116 * @param name the name of the environment variable 117 */ 118 void unsetEnv(const QString &name); 119 120 /** 121 * Empties the process' environment. 122 * 123 * Note that LD_LIBRARY_PATH/DYLD_LIBRARY_PATH is automatically added 124 * on *NIX. 125 * 126 * This function must be called before starting the process. 127 */ 128 void clearEnvironment(); 129 130 /** 131 * Set the program and the command line arguments. 132 * 133 * This function must be called before starting the process, obviously. 134 * 135 * @param exe the program to execute 136 * @param args the command line arguments for the program, 137 * one per list element 138 */ 139 void setProgram(const QString &exe, const QStringList &args = QStringList()); 140 141 /** 142 * @overload 143 * 144 * @param argv the program to execute and the command line arguments 145 * for the program, one per list element 146 */ 147 void setProgram(const QStringList &argv); 148 149 /** 150 * Append an element to the command line argument list for this process. 151 * 152 * If no executable is set yet, it will be set instead. 153 * 154 * For example, doing an "ls -l /usr/local/bin" can be achieved by: 155 * \code 156 * KProcess p; 157 * p << "ls" << "-l" << "/usr/local/bin"; 158 * ... 159 * \endcode 160 * 161 * This function must be called before starting the process, obviously. 162 * 163 * @param arg the argument to add 164 * @return a reference to this KProcess 165 */ 166 KProcess &operator<<(const QString &arg); 167 168 /** 169 * @overload 170 * 171 * @param args the arguments to add 172 * @return a reference to this KProcess 173 */ 174 KProcess &operator<<(const QStringList &args); 175 176 /** 177 * Clear the program and command line argument list. 178 */ 179 void clearProgram(); 180 181 /** 182 * Set a command to execute through a shell (a POSIX sh on *NIX 183 * and cmd.exe on Windows). 184 * 185 * Using this for anything but user-supplied commands is usually a bad 186 * idea, as the command's syntax depends on the platform. 187 * Redirections including pipes, etc. are better handled by the 188 * respective functions provided by QProcess. 189 * 190 * If KProcess determines that the command does not really need a 191 * shell, it will transparently execute it without one for performance 192 * reasons. 193 * 194 * This function must be called before starting the process, obviously. 195 * 196 * @param cmd the command to execute through a shell. 197 * The caller must make sure that all filenames etc. are properly 198 * quoted when passed as argument. Failure to do so often results in 199 * serious security holes. See KShell::quoteArg(). 200 */ 201 void setShellCommand(const QString &cmd); 202 203 /** 204 * Obtain the currently set program and arguments. 205 * 206 * @return a list, the first element being the program, the remaining ones 207 * being command line arguments to the program. 208 */ 209 QStringList program() const; 210 211 /** 212 * Start the process. 213 * 214 * @see QProcess::start(const QString &, const QStringList &, OpenMode) 215 */ 216 void start(); 217 218 /** 219 * Start the process, wait for it to finish, and return the exit code. 220 * 221 * This method is roughly equivalent to the sequence: 222 * @code 223 * start(); 224 * waitForFinished(msecs); 225 * return exitCode(); 226 * @endcode 227 * 228 * Unlike the other execute() variants this method is not static, 229 * so the process can be parametrized properly and talked to. 230 * 231 * @param msecs time to wait for process to exit before killing it 232 * @return -2 if the process could not be started, -1 if it crashed, 233 * otherwise its exit code 234 */ 235 int execute(int msecs = -1); 236 237 /** 238 * @overload 239 * 240 * @param exe the program to execute 241 * @param args the command line arguments for the program, 242 * one per list element 243 * @param msecs time to wait for process to exit before killing it 244 * @return -2 if the process could not be started, -1 if it crashed, 245 * otherwise its exit code 246 */ 247 static int execute(const QString &exe, const QStringList &args = QStringList(), int msecs = -1); 248 249 /** 250 * @overload 251 * 252 * @param argv the program to execute and the command line arguments 253 * for the program, one per list element 254 * @param msecs time to wait for process to exit before killing it 255 * @return -2 if the process could not be started, -1 if it crashed, 256 * otherwise its exit code 257 */ 258 static int execute(const QStringList &argv, int msecs = -1); 259 260 /** 261 * Start the process and detach from it. See QProcess::startDetached() 262 * for details. 263 * 264 * Unlike the other startDetached() variants this method is not static, 265 * so the process can be parametrized properly. 266 * @note Currently, only the setProgram()/setShellCommand() and 267 * setWorkingDirectory() parametrizations are supported. 268 * 269 * The KProcess object may be re-used immediately after calling this 270 * function. 271 * 272 * @return the PID of the started process or 0 on error 273 */ 274 int startDetached(); 275 276 /** 277 * @overload 278 * 279 * @param exe the program to start 280 * @param args the command line arguments for the program, 281 * one per list element 282 * @return the PID of the started process or 0 on error 283 */ 284 static int startDetached(const QString &exe, const QStringList &args = QStringList()); 285 286 /** 287 * @overload 288 * 289 * @param argv the program to start and the command line arguments 290 * for the program, one per list element 291 * @return the PID of the started process or 0 on error 292 */ 293 static int startDetached(const QStringList &argv); 294 295 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 78) 296 /** 297 * Obtain the process' ID as known to the system. 298 * 299 * Unlike with QProcess::pid(), this is a real PID also on Windows. 300 * 301 * This function can be called only while the process is running. 302 * It cannot be applied to detached processes. 303 * 304 * @return the process ID 305 * @deprecated since 5.78, use processId() 306 */ 307 KCOREADDONS_DEPRECATED_VERSION(5, 78, "Use processId()") 308 int pid() const; 309 #endif 310 311 protected: 312 /** 313 * @internal 314 */ 315 KProcess(KProcessPrivate *d, QObject *parent); 316 317 /** 318 * @internal 319 */ 320 std::unique_ptr<KProcessPrivate> const d_ptr; 321 322 private: 323 // hide those 324 #if QT_DEPRECATED_SINCE(5, 13) 325 using QProcess::readChannelMode; 326 using QProcess::setReadChannelMode; 327 #endif 328 using QProcess::processChannelMode; 329 using QProcess::setProcessChannelMode; 330 }; 331 332 #endif 333