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 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 **/
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 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
295protected:
296 /**
297 * @internal
298 */
299 KCOREADDONS_NO_EXPORT KProcess(KProcessPrivate *d, QObject *parent);
300
301 /**
302 * @internal
303 */
304 std::unique_ptr<KProcessPrivate> const d_ptr;
305
306private:
307 // hide those
308 using QProcess::processChannelMode;
309 using QProcess::setProcessChannelMode;
310};
311
312#endif
313

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