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