Mercurial > hg > octave-avbm
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 |