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

source code of kcoreaddons/src/lib/io/kprocess.h