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