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 | protected: |
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 | |
306 | private: |
307 | // hide those |
308 | using QProcess::processChannelMode; |
309 | using QProcess::setProcessChannelMode; |
310 | }; |
311 | |
312 | #endif |
313 | |