comparison gui/src/terminal/kprocess.cpp @ 13501:86d6c3b90ad7

Added new gui files.
author Jacob Dawid <jacob.dawid@googlemail.com>
date Sun, 17 Jul 2011 17:45:05 +0200
parents
children c70511cf64ee
comparison
equal deleted inserted replaced
13500:40bd465b6c79 13501:86d6c3b90ad7
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 #include "kprocess_p.h"
23
24 #include <qfile.h>
25
26 #ifdef Q_OS_WIN
27 # include <windows.h>
28 #else
29 # include <unistd.h>
30 # include <errno.h>
31 #endif
32
33 #ifndef Q_OS_WIN
34 # define STD_OUTPUT_HANDLE 1
35 # define STD_ERROR_HANDLE 2
36 #endif
37
38 #ifdef _WIN32_WCE
39 #include <stdio.h>
40 #endif
41
42 void KProcessPrivate::writeAll(const QByteArray &buf, int fd)
43 {
44 #ifdef Q_OS_WIN
45 #ifndef _WIN32_WCE
46 HANDLE h = GetStdHandle(fd);
47 if (h) {
48 DWORD wr;
49 WriteFile(h, buf.data(), buf.size(), &wr, 0);
50 }
51 #else
52 fwrite(buf.data(), 1, buf.size(), (FILE*)fd);
53 #endif
54 #else
55 int off = 0;
56 do {
57 int ret = ::write(fd, buf.data() + off, buf.size() - off);
58 if (ret < 0) {
59 if (errno != EINTR)
60 return;
61 } else {
62 off += ret;
63 }
64 } while (off < buf.size());
65 #endif
66 }
67
68 void KProcessPrivate::forwardStd(KProcess::ProcessChannel good, int fd)
69 {
70 Q_Q(KProcess);
71
72 QProcess::ProcessChannel oc = q->readChannel();
73 q->setReadChannel(good);
74 writeAll(q->readAll(), fd);
75 q->setReadChannel(oc);
76 }
77
78 void KProcessPrivate::_k_forwardStdout()
79 {
80 #ifndef _WIN32_WCE
81 forwardStd(KProcess::StandardOutput, STD_OUTPUT_HANDLE);
82 #else
83 forwardStd(KProcess::StandardOutput, (int)stdout);
84 #endif
85 }
86
87 void KProcessPrivate::_k_forwardStderr()
88 {
89 #ifndef _WIN32_WCE
90 forwardStd(KProcess::StandardError, STD_ERROR_HANDLE);
91 #else
92 forwardStd(KProcess::StandardError, (int)stderr);
93 #endif
94 }
95
96 /////////////////////////////
97 // public member functions //
98 /////////////////////////////
99
100 KProcess::KProcess(QObject *parent) :
101 QProcess(parent),
102 d_ptr(new KProcessPrivate)
103 {
104 d_ptr->q_ptr = this;
105 setOutputChannelMode(ForwardedChannels);
106 }
107
108 KProcess::KProcess(KProcessPrivate *d, QObject *parent) :
109 QProcess(parent),
110 d_ptr(d)
111 {
112 d_ptr->q_ptr = this;
113 setOutputChannelMode(ForwardedChannels);
114 }
115
116 KProcess::~KProcess()
117 {
118 delete d_ptr;
119 }
120
121 void KProcess::setOutputChannelMode(OutputChannelMode mode)
122 {
123 Q_D(KProcess);
124
125 d->outputChannelMode = mode;
126 disconnect(this, SIGNAL(readyReadStandardOutput()));
127 disconnect(this, SIGNAL(readyReadStandardError()));
128 switch (mode) {
129 case OnlyStdoutChannel:
130 connect(this, SIGNAL(readyReadStandardError()), SLOT(_k_forwardStderr()));
131 break;
132 case OnlyStderrChannel:
133 connect(this, SIGNAL(readyReadStandardOutput()), SLOT(_k_forwardStdout()));
134 break;
135 default:
136 QProcess::setProcessChannelMode((ProcessChannelMode)mode);
137 return;
138 }
139 QProcess::setProcessChannelMode(QProcess::SeparateChannels);
140 }
141
142 KProcess::OutputChannelMode KProcess::outputChannelMode() const
143 {
144 Q_D(const KProcess);
145
146 return d->outputChannelMode;
147 }
148
149 void KProcess::setNextOpenMode(QIODevice::OpenMode mode)
150 {
151 Q_D(KProcess);
152
153 d->openMode = mode;
154 }
155
156 #define DUMMYENV "_KPROCESS_DUMMY_="
157
158 void KProcess::clearEnvironment()
159 {
160 setEnvironment(QStringList() << QString::fromLatin1(DUMMYENV));
161 }
162
163 void KProcess::setEnv(const QString &name, const QString &value, bool overwrite)
164 {
165 QStringList env = environment();
166 if (env.isEmpty()) {
167 env = systemEnvironment();
168 env.removeAll(QString::fromLatin1(DUMMYENV));
169 }
170 QString fname(name);
171 fname.append(QLatin1Char('='));
172 for (QStringList::Iterator it = env.begin(); it != env.end(); ++it)
173 if ((*it).startsWith(fname)) {
174 if (overwrite) {
175 *it = fname.append(value);
176 setEnvironment(env);
177 }
178 return;
179 }
180 env.append(fname.append(value));
181 setEnvironment(env);
182 }
183
184 void KProcess::unsetEnv(const QString &name)
185 {
186 QStringList env = environment();
187 if (env.isEmpty()) {
188 env = systemEnvironment();
189 env.removeAll(QString::fromLatin1(DUMMYENV));
190 }
191 QString fname(name);
192 fname.append(QLatin1Char('='));
193 for (QStringList::Iterator it = env.begin(); it != env.end(); ++it)
194 if ((*it).startsWith(fname)) {
195 env.erase(it);
196 if (env.isEmpty())
197 env.append(QString::fromLatin1(DUMMYENV));
198 setEnvironment(env);
199 return;
200 }
201 }
202
203 void KProcess::setProgram(const QString &exe, const QStringList &args)
204 {
205 Q_D(KProcess);
206
207 d->prog = exe;
208 d->args = args;
209 #ifdef Q_OS_WIN
210 setNativeArguments(QString());
211 #endif
212 }
213
214 void KProcess::setProgram(const QStringList &argv)
215 {
216 Q_D(KProcess);
217
218 Q_ASSERT( !argv.isEmpty() );
219 d->args = argv;
220 d->prog = d->args.takeFirst();
221 #ifdef Q_OS_WIN
222 setNativeArguments(QString());
223 #endif
224 }
225
226 KProcess &KProcess::operator<<(const QString &arg)
227 {
228 Q_D(KProcess);
229
230 if (d->prog.isEmpty())
231 d->prog = arg;
232 else
233 d->args << arg;
234 return *this;
235 }
236
237 KProcess &KProcess::operator<<(const QStringList &args)
238 {
239 Q_D(KProcess);
240
241 if (d->prog.isEmpty())
242 setProgram(args);
243 else
244 d->args << args;
245 return *this;
246 }
247
248 void KProcess::clearProgram()
249 {
250 Q_D(KProcess);
251
252 d->prog.clear();
253 d->args.clear();
254 #ifdef Q_OS_WIN
255 setNativeArguments(QString());
256 #endif
257 }
258
259 void KProcess::setShellCommand(const QString &cmd)
260 {
261 Q_D(KProcess);
262 d->args.clear();
263 d->prog = QString::fromLatin1("/bin/sh");
264 d->args << QString::fromLatin1("-c") << cmd;
265 }
266
267 QStringList KProcess::program() const
268 {
269 Q_D(const KProcess);
270
271 QStringList argv = d->args;
272 argv.prepend(d->prog);
273 return argv;
274 }
275
276 void KProcess::start()
277 {
278 Q_D(KProcess);
279
280 QProcess::start(d->prog, d->args, d->openMode);
281 }
282
283 int KProcess::execute(int msecs)
284 {
285 start();
286 if (!waitForFinished(msecs)) {
287 kill();
288 waitForFinished(-1);
289 return -2;
290 }
291 return (exitStatus() == QProcess::NormalExit) ? exitCode() : -1;
292 }
293
294 // static
295 int KProcess::execute(const QString &exe, const QStringList &args, int msecs)
296 {
297 KProcess p;
298 p.setProgram(exe, args);
299 return p.execute(msecs);
300 }
301
302 // static
303 int KProcess::execute(const QStringList &argv, int msecs)
304 {
305 KProcess p;
306 p.setProgram(argv);
307 return p.execute(msecs);
308 }
309
310 int KProcess::startDetached()
311 {
312 Q_D(KProcess);
313
314 qint64 pid;
315 if (!QProcess::startDetached(d->prog, d->args, workingDirectory(), &pid))
316 return 0;
317 return (int) pid;
318 }
319
320 // static
321 int KProcess::startDetached(const QString &exe, const QStringList &args)
322 {
323 qint64 pid;
324 if (!QProcess::startDetached(exe, args, QString(), &pid))
325 return 0;
326 return (int) pid;
327 }
328
329 // static
330 int KProcess::startDetached(const QStringList &argv)
331 {
332 QStringList args = argv;
333 QString prog = args.takeFirst();
334 return startDetached(prog, args);
335 }
336
337 int KProcess::pid() const
338 {
339 #ifdef Q_OS_UNIX
340 return (int) QProcess::pid();
341 #else
342 return QProcess::pid() ? QProcess::pid()->dwProcessId : 0;
343 #endif
344 }
345