source: trunk/src/corelib/io/qprocess.cpp@ 769

Last change on this file since 769 was 769, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.3 sources from branches/vendor/nokia/qt.

File size: 68.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42//#define QPROCESS_DEBUG
43
44#if defined QPROCESS_DEBUG
45#include <qdebug.h>
46#include <qstring.h>
47#include <ctype.h>
48#if !defined(Q_OS_WINCE)
49#include <errno.h>
50#endif
51
52QT_BEGIN_NAMESPACE
53/*
54 Returns a human readable representation of the first \a len
55 characters in \a data.
56*/
57static QByteArray qt_prettyDebug(const char *data, int len, int maxSize)
58{
59 if (!data) return "(null)";
60 QByteArray out;
61 for (int i = 0; i < len && i < maxSize; ++i) {
62 char c = data[i];
63 if (isprint(c)) {
64 out += c;
65 } else switch (c) {
66 case '\n': out += "\\n"; break;
67 case '\r': out += "\\r"; break;
68 case '\t': out += "\\t"; break;
69 default:
70 char buf[5];
71 qsnprintf(buf, sizeof(buf), "\\%3o", c);
72 buf[4] = '\0';
73 out += QByteArray(buf);
74 }
75 }
76
77 if (len < maxSize)
78 out += "...";
79
80 return out;
81}
82
83QT_END_NAMESPACE
84
85#endif
86
87#include "qprocess.h"
88#include "qprocess_p.h"
89
90#include <qbytearray.h>
91#include <qdatetime.h>
92#include <qcoreapplication.h>
93#include <qsocketnotifier.h>
94#include <qtimer.h>
95
96#ifdef Q_WS_WIN
97#include <private/qwineventnotifier_p.h>
98#endif
99
100#ifdef Q_OS_SYMBIAN
101#include <e32std.h>
102#endif
103
104#ifndef QT_NO_PROCESS
105
106QT_BEGIN_NAMESPACE
107
108/*!
109 \class QProcessEnvironment
110
111 \brief The QProcessEnvironment class holds the environment variables that
112 can be passed to a program.
113
114 \ingroup io
115 \ingroup misc
116 \mainclass
117 \reentrant
118 \since 4.6
119
120 A process's environment is composed of a set of key=value pairs known as
121 environment variables. The QProcessEnvironment class wraps that concept
122 and allows easy manipulation of those variables. It's meant to be used
123 along with QProcess, to set the environment for child processes. It
124 cannot be used to change the current process's environment.
125
126 The environment of the calling process can be obtained using
127 QProcessEnvironment::systemEnvironment().
128
129 On Unix systems, the variable names are case-sensitive. For that reason,
130 this class will not touch the names of the variables. Note as well that
131 Unix environment allows both variable names and contents to contain arbitrary
132 binary data (except for the NUL character), but this is not supported by
133 QProcessEnvironment. This class only supports names and values that are
134 encodable by the current locale settings (see QTextCodec::codecForLocale).
135
136 On Windows, the variable names are case-insensitive. Therefore,
137 QProcessEnvironment will always uppercase the names and do case-insensitive
138 comparisons.
139
140 On Windows CE, the concept of environment does not exist. This class will
141 keep the values set for compatibility with other platforms, but the values
142 set will have no effect on the processes being created.
143
144 \sa QProcess, QProcess::systemEnvironment(), QProcess::setProcessEnvironment()
145*/
146#ifdef Q_OS_WIN
147static inline QProcessEnvironmentPrivate::Unit prepareName(const QString &name)
148{ return name.toUpper(); }
149static inline QProcessEnvironmentPrivate::Unit prepareName(const QByteArray &name)
150{ return QString::fromLocal8Bit(name).toUpper(); }
151static inline QString nameToString(const QProcessEnvironmentPrivate::Unit &name)
152{ return name; }
153static inline QProcessEnvironmentPrivate::Unit prepareValue(const QString &value)
154{ return value; }
155static inline QProcessEnvironmentPrivate::Unit prepareValue(const QByteArray &value)
156{ return QString::fromLocal8Bit(value); }
157static inline QString valueToString(const QProcessEnvironmentPrivate::Unit &value)
158{ return value; }
159static inline QByteArray valueToByteArray(const QProcessEnvironmentPrivate::Unit &value)
160{ return value.toLocal8Bit(); }
161#else
162static inline QProcessEnvironmentPrivate::Unit prepareName(const QByteArray &name)
163{ return name; }
164static inline QProcessEnvironmentPrivate::Unit prepareName(const QString &name)
165{ return name.toLocal8Bit(); }
166static inline QString nameToString(const QProcessEnvironmentPrivate::Unit &name)
167{ return QString::fromLocal8Bit(name); }
168static inline QProcessEnvironmentPrivate::Unit prepareValue(const QByteArray &value)
169{ return value; }
170static inline QProcessEnvironmentPrivate::Unit prepareValue(const QString &value)
171{ return value.toLocal8Bit(); }
172static inline QString valueToString(const QProcessEnvironmentPrivate::Unit &value)
173{ return QString::fromLocal8Bit(value); }
174static inline QByteArray valueToByteArray(const QProcessEnvironmentPrivate::Unit &value)
175{ return value; }
176#endif
177
178template<> void QSharedDataPointer<QProcessEnvironmentPrivate>::detach()
179{
180 if (d && d->ref == 1)
181 return;
182 QProcessEnvironmentPrivate *x = (d ? new QProcessEnvironmentPrivate(*d)
183 : new QProcessEnvironmentPrivate);
184 x->ref.ref();
185 if (d && !d->ref.deref())
186 delete d;
187 d = x;
188}
189
190QStringList QProcessEnvironmentPrivate::toList() const
191{
192 QStringList result;
193 QHash<Unit, Unit>::ConstIterator it = hash.constBegin(),
194 end = hash.constEnd();
195 for ( ; it != end; ++it) {
196 QString data = nameToString(it.key());
197 QString value = valueToString(it.value());
198 data.reserve(data.length() + value.length() + 1);
199 data.append(QLatin1Char('='));
200 data.append(value);
201 result << data;
202 }
203 return result;
204}
205
206QProcessEnvironment QProcessEnvironmentPrivate::fromList(const QStringList &list)
207{
208 QProcessEnvironment env;
209 QStringList::ConstIterator it = list.constBegin(),
210 end = list.constEnd();
211 for ( ; it != end; ++it) {
212 int pos = it->indexOf(QLatin1Char('='));
213 if (pos < 1)
214 continue;
215
216 QString value = it->mid(pos + 1);
217 QString name = *it;
218 name.truncate(pos);
219 env.insert(name, value);
220 }
221 return env;
222}
223
224/*!
225 Creates a new QProcessEnvironment object. This constructor creates an
226 empty environment. If set on a QProcess, this will cause the current
227 environment variables to be removed.
228*/
229QProcessEnvironment::QProcessEnvironment()
230 : d(0)
231{
232}
233
234/*!
235 Frees the resources associated with this QProcessEnvironment object.
236*/
237QProcessEnvironment::~QProcessEnvironment()
238{
239}
240
241/*!
242 Creates a QProcessEnvironment object that is a copy of \a other.
243*/
244QProcessEnvironment::QProcessEnvironment(const QProcessEnvironment &other)
245 : d(other.d)
246{
247}
248
249/*!
250 Copies the contents of the \a other QProcessEnvironment object into this
251 one.
252*/
253QProcessEnvironment &QProcessEnvironment::operator=(const QProcessEnvironment &other)
254{
255 d = other.d;
256 return *this;
257}
258
259/*!
260 \fn bool QProcessEnvironment::operator !=(const QProcessEnvironment &other) const
261
262 Returns true if this and the \a other QProcessEnvironment objects are different.
263
264 \sa operator==()
265*/
266
267/*!
268 Returns true if this and the \a other QProcessEnvironment objects are equal.
269
270 Two QProcessEnvironment objects are considered equal if they have the same
271 set of key=value pairs. The comparison of keys is done case-sensitive on
272 platforms where the environment is case-sensitive.
273
274 \sa operator!=(), contains()
275*/
276bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const
277{
278 return d == other.d || (d && other.d && d->hash == other.d->hash);
279}
280
281/*!
282 Returns true if this QProcessEnvironment object is empty: that is
283 there are no key=value pairs set.
284
285 \sa clear(), systemEnvironment(), insert()
286*/
287bool QProcessEnvironment::isEmpty() const
288{
289 return d ? d->hash.isEmpty() : true;
290}
291
292/*!
293 Removes all key=value pairs from this QProcessEnvironment object, making
294 it empty.
295
296 \sa isEmpty(), systemEnvironment()
297*/
298void QProcessEnvironment::clear()
299{
300 if (d)
301 d->hash.clear();
302}
303
304/*!
305 Returns true if the environment variable of name \a name is found in
306 this QProcessEnvironment object.
307
308 On Windows, variable names are case-insensitive, so the key is converted
309 to uppercase before searching. On other systems, names are case-sensitive
310 so no trasformation is applied.
311
312 \sa insert(), value()
313*/
314bool QProcessEnvironment::contains(const QString &name) const
315{
316 return d ? d->hash.contains(prepareName(name)) : false;
317}
318
319/*!
320 Inserts the environment variable of name \a name and contents \a value
321 into this QProcessEnvironment object. If that variable already existed,
322 it is replaced by the new value.
323
324 On Windows, variable names are case-insensitive, so this function always
325 uppercases the variable name before inserting. On other systems, names
326 are case-sensitive, so no transformation is applied.
327
328 On most systems, inserting a variable with no contents will have the
329 same effect for applications as if the variable had not been set at all.
330 However, to guarantee that there are no incompatibilities, to remove a
331 variable, please use the remove() function.
332
333 \sa contains(), remove(), value()
334*/
335void QProcessEnvironment::insert(const QString &name, const QString &value)
336{
337 // d detaches from null
338 d->hash.insert(prepareName(name), prepareValue(value));
339}
340
341/*!
342 Removes the environment variable identified by \a name from this
343 QProcessEnvironment object. If that variable did not exist before,
344 nothing happens.
345
346 On Windows, variable names are case-insensitive, so the key is converted
347 to uppercase before searching. On other systems, names are case-sensitive
348 so no trasformation is applied.
349
350 \sa contains(), insert(), value()
351*/
352void QProcessEnvironment::remove(const QString &name)
353{
354 if (d)
355 d->hash.remove(prepareName(name));
356}
357
358/*!
359 Searches this QProcessEnvironment object for a variable identified by
360 \a name and returns its value. If the variable is not found in this object,
361 then \a defaultValue is returned instead.
362
363 On Windows, variable names are case-insensitive, so the key is converted
364 to uppercase before searching. On other systems, names are case-sensitive
365 so no trasformation is applied.
366
367 \sa contains(), insert(), remove()
368*/
369QString QProcessEnvironment::value(const QString &name, const QString &defaultValue) const
370{
371 if (!d)
372 return defaultValue;
373
374 QProcessEnvironmentPrivate::Hash::ConstIterator it = d->hash.constFind(prepareName(name));
375 if (it == d->hash.constEnd())
376 return defaultValue;
377
378 return valueToString(it.value());
379}
380
381/*!
382 Converts this QProcessEnvironment object into a list of strings, one for
383 each environment variable that is set. The environment variable's name
384 and its value are separated by an equal character ('=').
385
386 The QStringList contents returned by this function are suitable for use
387 with the QProcess::setEnvironment function. However, it is recommended
388 to use QProcess::setProcessEnvironment instead since that will avoid
389 unnecessary copying of the data.
390
391 \sa systemEnvironment(), QProcess::systemEnvironment(), QProcess::environment(),
392 QProcess::setEnvironment()
393*/
394QStringList QProcessEnvironment::toStringList() const
395{
396 return d ? d->toList() : QStringList();
397}
398
399void QProcessPrivate::Channel::clear()
400{
401 switch (type) {
402 case PipeSource:
403 Q_ASSERT(process);
404 process->stdinChannel.type = Normal;
405 process->stdinChannel.process = 0;
406 break;
407 case PipeSink:
408 Q_ASSERT(process);
409 process->stdoutChannel.type = Normal;
410 process->stdoutChannel.process = 0;
411 break;
412 }
413
414 type = Normal;
415 file.clear();
416 process = 0;
417}
418
419/*! \fn bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid)
420
421\internal
422 */
423
424/*!
425 \class QProcess
426
427 \brief The QProcess class is used to start external programs and
428 to communicate with them.
429
430 \ingroup io
431
432 \reentrant
433
434 \section1 Running a Process
435
436 To start a process, pass the name and command line arguments of
437 the program you want to run as arguments to start(). Arguments
438 are supplied as individual strings in a QStringList.
439
440 For example, the following code snippet runs the analog clock
441 example in the Motif style on X11 platforms by passing strings
442 containing "-style" and "motif" as two items in the list of
443 arguments:
444
445 \snippet doc/src/snippets/qprocess/qprocess-simpleexecution.cpp 0
446 \dots
447 \snippet doc/src/snippets/qprocess/qprocess-simpleexecution.cpp 1
448 \snippet doc/src/snippets/qprocess/qprocess-simpleexecution.cpp 2
449
450 QProcess then enters the \l Starting state, and when the program
451 has started, QProcess enters the \l Running state and emits
452 started().
453
454 QProcess allows you to treat a process as a sequential I/O
455 device. You can write to and read from the process just as you
456 would access a network connection using QTcpSocket. You can then
457 write to the process's standard input by calling write(), and
458 read the standard output by calling read(), readLine(), and
459 getChar(). Because it inherits QIODevice, QProcess can also be
460 used as an input source for QXmlReader, or for generating data to
461 be uploaded using QFtp.
462
463 \note On Windows CE and Symbian, reading and writing to a process
464 is not supported.
465
466 When the process exits, QProcess reenters the \l NotRunning state
467 (the initial state), and emits finished().
468
469 The finished() signal provides the exit code and exit status of
470 the process as arguments, and you can also call exitCode() to
471 obtain the exit code of the last process that finished, and
472 exitStatus() to obtain its exit status. If an error occurs at
473 any point in time, QProcess will emit the error() signal. You
474 can also call error() to find the type of error that occurred
475 last, and state() to find the current process state.
476
477 \section1 Communicating via Channels
478
479 Processes have two predefined output channels: The standard
480 output channel (\c stdout) supplies regular console output, and
481 the standard error channel (\c stderr) usually supplies the
482 errors that are printed by the process. These channels represent
483 two separate streams of data. You can toggle between them by
484 calling setReadChannel(). QProcess emits readyRead() when data is
485 available on the current read channel. It also emits
486 readyReadStandardOutput() when new standard output data is
487 available, and when new standard error data is available,
488 readyReadStandardError() is emitted. Instead of calling read(),
489 readLine(), or getChar(), you can explicitly read all data from
490 either of the two channels by calling readAllStandardOutput() or
491 readAllStandardError().
492
493 The terminology for the channels can be misleading. Be aware that
494 the process's output channels correspond to QProcess's
495 \e read channels, whereas the process's input channels correspond
496 to QProcess's \e write channels. This is because what we read
497 using QProcess is the process's output, and what we write becomes
498 the process's input.
499
500 QProcess can merge the two output channels, so that standard
501 output and standard error data from the running process both use
502 the standard output channel. Call setProcessChannelMode() with
503 MergedChannels before starting the process to activative
504 this feature. You also have the option of forwarding the output of
505 the running process to the calling, main process, by passing
506 ForwardedChannels as the argument.
507
508 Certain processes need special environment settings in order to
509 operate. You can set environment variables for your process by
510 calling setEnvironment(). To set a working directory, call
511 setWorkingDirectory(). By default, processes are run in the
512 current working directory of the calling process.
513
514 \note On Symbian, setting environment or working directory
515 is not supported. The working directory will always be the private
516 directory of the running process.
517
518 \section1 Synchronous Process API
519
520 QProcess provides a set of functions which allow it to be used
521 without an event loop, by suspending the calling thread until
522 certain signals are emitted:
523
524 \list
525 \o waitForStarted() blocks until the process has started.
526
527 \o waitForReadyRead() blocks until new data is
528 available for reading on the current read channel.
529
530 \o waitForBytesWritten() blocks until one payload of
531 data has been written to the process.
532
533 \o waitForFinished() blocks until the process has finished.
534 \endlist
535
536 Calling these functions from the main thread (the thread that
537 calls QApplication::exec()) may cause your user interface to
538 freeze.
539
540 The following example runs \c gzip to compress the string "Qt
541 rocks!", without an event loop:
542
543 \snippet doc/src/snippets/process/process.cpp 0
544
545 \section1 Notes for Windows and OS/2 Users
546
547 Some Windows and OS/2 commands (for example, \c dir) are not provided
548 by separate applications, but by the command interpreter itself.
549 If you attempt to use QProcess to execute these commands directly,
550 it won't work. One possible solution is to execute the command
551 interpreter itself (\c{cmd.exe} on some Windows systems), and ask
552 the interpreter to execute the desired command.
553
554 \section1 Symbian Platform Security Requirements
555
556 On Symbian, processes which use the functions kill() or terminate()
557 must have the \c PowerMgmt platform security capability. If the client
558 process lacks this capability, these functions will fail.
559
560 Platform security capabilities are added via the
561 \l{qmake-variable-reference.html#target-capability}{TARGET.CAPABILITY}
562 qmake variable.
563
564 \sa QBuffer, QFile, QTcpSocket
565*/
566
567/*!
568 \enum QProcess::ProcessChannel
569
570 This enum describes the process channels used by the running process.
571 Pass one of these values to setReadChannel() to set the
572 current read channel of QProcess.
573
574 \value StandardOutput The standard output (stdout) of the running
575 process.
576
577 \value StandardError The standard error (stderr) of the running
578 process.
579
580 \sa setReadChannel()
581*/
582
583/*!
584 \enum QProcess::ProcessChannelMode
585
586 This enum describes the process channel modes of QProcess. Pass
587 one of these values to setProcessChannelMode() to set the
588 current read channel mode.
589
590 \value SeparateChannels QProcess manages the output of the
591 running process, keeping standard output and standard error data
592 in separate internal buffers. You can select the QProcess's
593 current read channel by calling setReadChannel(). This is the
594 default channel mode of QProcess.
595
596 \value MergedChannels QProcess merges the output of the running
597 process into the standard output channel (\c stdout). The
598 standard error channel (\c stderr) will not receive any data. The
599 standard output and standard error data of the running process
600 are interleaved.
601
602 \value ForwardedChannels QProcess forwards the output of the
603 running process onto the main process. Anything the child process
604 writes to its standard output and standard error will be written
605 to the standard output and standard error of the main process.
606
607 \sa setProcessChannelMode()
608*/
609
610/*!
611 \enum QProcess::ProcessError
612
613 This enum describes the different types of errors that are
614 reported by QProcess.
615
616 \value FailedToStart The process failed to start. Either the
617 invoked program is missing, or you may have insufficient
618 permissions to invoke the program.
619
620 \value Crashed The process crashed some time after starting
621 successfully.
622
623 \value Timedout The last waitFor...() function timed out. The
624 state of QProcess is unchanged, and you can try calling
625 waitFor...() again.
626
627 \value WriteError An error occurred when attempting to write to the
628 process. For example, the process may not be running, or it may
629 have closed its input channel.
630
631 \value ReadError An error occurred when attempting to read from
632 the process. For example, the process may not be running.
633
634 \value UnknownError An unknown error occurred. This is the default
635 return value of error().
636
637 \sa error()
638*/
639
640/*!
641 \enum QProcess::ProcessState
642
643 This enum describes the different states of QProcess.
644
645 \value NotRunning The process is not running.
646
647 \value Starting The process is starting, but the program has not
648 yet been invoked.
649
650 \value Running The process is running and is ready for reading and
651 writing.
652
653 \sa state()
654*/
655
656/*!
657 \enum QProcess::ExitStatus
658
659 This enum describes the different exit statuses of QProcess.
660
661 \value NormalExit The process exited normally.
662
663 \value CrashExit The process crashed.
664
665 \sa exitStatus()
666*/
667
668/*!
669 \fn void QProcess::error(QProcess::ProcessError error)
670
671 This signal is emitted when an error occurs with the process. The
672 specified \a error describes the type of error that occurred.
673*/
674
675/*!
676 \fn void QProcess::started()
677
678 This signal is emitted by QProcess when the process has started,
679 and state() returns \l Running.
680*/
681
682/*!
683 \fn void QProcess::stateChanged(QProcess::ProcessState newState)
684
685 This signal is emitted whenever the state of QProcess changes. The
686 \a newState argument is the state QProcess changed to.
687*/
688
689/*!
690 \fn void QProcess::finished(int exitCode)
691 \obsolete
692 \overload
693
694 Use finished(int exitCode, QProcess::ExitStatus status) instead.
695*/
696
697/*!
698 \fn void QProcess::finished(int exitCode, QProcess::ExitStatus exitStatus)
699
700 This signal is emitted when the process finishes. \a exitCode is the exit
701 code of the process, and \a exitStatus is the exit status. After the
702 process has finished, the buffers in QProcess are still intact. You can
703 still read any data that the process may have written before it finished.
704
705 \sa exitStatus()
706*/
707
708/*!
709 \fn void QProcess::readyReadStandardOutput()
710
711 This signal is emitted when the process has made new data
712 available through its standard output channel (\c stdout). It is
713 emitted regardless of the current \l{readChannel()}{read channel}.
714
715 \sa readAllStandardOutput(), readChannel()
716*/
717
718/*!
719 \fn void QProcess::readyReadStandardError()
720
721 This signal is emitted when the process has made new data
722 available through its standard error channel (\c stderr). It is
723 emitted regardless of the current \l{readChannel()}{read
724 channel}.
725
726 \sa readAllStandardError(), readChannel()
727*/
728
729/*! \internal
730*/
731QProcessPrivate::QProcessPrivate()
732{
733 processChannel = QProcess::StandardOutput;
734 processChannelMode = QProcess::SeparateChannels;
735 processError = QProcess::UnknownError;
736 processState = QProcess::NotRunning;
737 pid = 0;
738 sequenceNumber = 0;
739 exitCode = 0;
740 exitStatus = QProcess::NormalExit;
741 startupSocketNotifier = 0;
742 deathNotifier = 0;
743 notifier = 0;
744 pipeWriter = 0;
745#ifndef Q_OS_OS2
746 childStartedPipe[0] = INVALID_Q_PIPE;
747 childStartedPipe[1] = INVALID_Q_PIPE;
748 deathPipe[0] = INVALID_Q_PIPE;
749 deathPipe[1] = INVALID_Q_PIPE;
750#endif
751 exitCode = 0;
752 crashed = false;
753 dying = false;
754 emittedReadyRead = false;
755 emittedBytesWritten = false;
756#ifdef Q_WS_WIN
757 pipeWriter = 0;
758 processFinishedNotifier = 0;
759#endif // Q_WS_WIN
760#ifdef Q_OS_UNIX
761 serial = 0;
762#endif
763#ifdef Q_OS_SYMBIAN
764 symbianProcess = NULL;
765 processLaunched = false;
766#endif
767#ifdef Q_OS_OS2
768 init();
769#endif
770}
771
772/*! \internal
773*/
774QProcessPrivate::~QProcessPrivate()
775{
776#ifdef Q_OS_OS2
777 uninit();
778#endif
779 if (stdinChannel.process)
780 stdinChannel.process->stdoutChannel.clear();
781 if (stdoutChannel.process)
782 stdoutChannel.process->stdinChannel.clear();
783}
784
785/*! \internal
786*/
787void QProcessPrivate::cleanup()
788{
789 q_func()->setProcessState(QProcess::NotRunning);
790#ifdef Q_OS_WIN
791 if (pid) {
792 CloseHandle(pid->hThread);
793 CloseHandle(pid->hProcess);
794 delete pid;
795 pid = 0;
796 }
797 if (processFinishedNotifier) {
798 processFinishedNotifier->setEnabled(false);
799 qDeleteInEventHandler(processFinishedNotifier);
800 processFinishedNotifier = 0;
801 }
802
803#endif
804 pid = 0;
805 sequenceNumber = 0;
806 dying = false;
807
808 if (stdoutChannel.notifier) {
809 stdoutChannel.notifier->setEnabled(false);
810 qDeleteInEventHandler(stdoutChannel.notifier);
811 stdoutChannel.notifier = 0;
812 }
813 if (stderrChannel.notifier) {
814 stderrChannel.notifier->setEnabled(false);
815 qDeleteInEventHandler(stderrChannel.notifier);
816 stderrChannel.notifier = 0;
817 }
818 if (stdinChannel.notifier) {
819 stdinChannel.notifier->setEnabled(false);
820 qDeleteInEventHandler(stdinChannel.notifier);
821 stdinChannel.notifier = 0;
822 }
823 if (startupSocketNotifier) {
824 startupSocketNotifier->setEnabled(false);
825 qDeleteInEventHandler(startupSocketNotifier);
826 startupSocketNotifier = 0;
827 }
828 if (deathNotifier) {
829 deathNotifier->setEnabled(false);
830 qDeleteInEventHandler(deathNotifier);
831 deathNotifier = 0;
832 }
833 if (notifier) {
834 qDeleteInEventHandler(notifier);
835 notifier = 0;
836 }
837 destroyPipe(stdoutChannel.pipe);
838 destroyPipe(stderrChannel.pipe);
839 destroyPipe(stdinChannel.pipe);
840#ifndef Q_OS_OS2
841 destroyPipe(childStartedPipe);
842 destroyPipe(deathPipe);
843#else
844 pipeData[InPipe].bytesLeft = 0;
845 pipeData[OutPipe].bytesLeft = pipeData[ErrPipe].bytesLeft = 0;
846 pipeData[InPipe].newBytes = 0;
847 pipeData[OutPipe].newBytes = pipeData[ErrPipe].newBytes = 0;
848#endif
849#ifdef Q_OS_UNIX
850 serial = 0;
851#endif
852#ifdef Q_OS_SYMBIAN
853 if (symbianProcess) {
854 symbianProcess->Close();
855 delete symbianProcess;
856 symbianProcess = NULL;
857 }
858#endif
859}
860
861/*! \internal
862*/
863bool QProcessPrivate::_q_canReadStandardOutput()
864{
865 Q_Q(QProcess);
866 qint64 available = bytesAvailableFromStdout();
867 if (available == 0) {
868 if (stdoutChannel.notifier)
869 stdoutChannel.notifier->setEnabled(false);
870 destroyPipe(stdoutChannel.pipe);
871#if defined QPROCESS_DEBUG
872 qDebug("QProcessPrivate::canReadStandardOutput(), 0 bytes available");
873#endif
874 return false;
875 }
876
877 char *ptr = outputReadBuffer.reserve(available);
878 qint64 readBytes = readFromStdout(ptr, available);
879 if (readBytes == -1) {
880 processError = QProcess::ReadError;
881 q->setErrorString(QProcess::tr("Error reading from process"));
882 emit q->error(processError);
883#if defined QPROCESS_DEBUG
884 qDebug("QProcessPrivate::canReadStandardOutput(), failed to read from the process");
885#endif
886 return false;
887 }
888#if defined QPROCESS_DEBUG
889 qDebug("QProcessPrivate::canReadStandardOutput(), read %d bytes from the process' output",
890 int(readBytes));
891#endif
892
893 if (stdoutChannel.closed) {
894 outputReadBuffer.chop(readBytes);
895 return false;
896 }
897
898 outputReadBuffer.chop(available - readBytes);
899
900 bool didRead = false;
901 if (readBytes == 0) {
902 if (stdoutChannel.notifier)
903 stdoutChannel.notifier->setEnabled(false);
904 } else if (processChannel == QProcess::StandardOutput) {
905 didRead = true;
906 if (!emittedReadyRead) {
907 emittedReadyRead = true;
908 emit q->readyRead();
909 emittedReadyRead = false;
910 }
911 }
912 emit q->readyReadStandardOutput();
913 return didRead;
914}
915
916/*! \internal
917*/
918bool QProcessPrivate::_q_canReadStandardError()
919{
920 Q_Q(QProcess);
921 qint64 available = bytesAvailableFromStderr();
922 if (available == 0) {
923 if (stderrChannel.notifier)
924 stderrChannel.notifier->setEnabled(false);
925 destroyPipe(stderrChannel.pipe);
926 return false;
927 }
928
929 char *ptr = errorReadBuffer.reserve(available);
930 qint64 readBytes = readFromStderr(ptr, available);
931 if (readBytes == -1) {
932 processError = QProcess::ReadError;
933 q->setErrorString(QProcess::tr("Error reading from process"));
934 emit q->error(processError);
935 return false;
936 }
937 if (stderrChannel.closed) {
938 errorReadBuffer.chop(readBytes);
939 return false;
940 }
941
942 errorReadBuffer.chop(available - readBytes);
943
944 bool didRead = false;
945 if (readBytes == 0) {
946 if (stderrChannel.notifier)
947 stderrChannel.notifier->setEnabled(false);
948 } else if (processChannel == QProcess::StandardError) {
949 didRead = true;
950 if (!emittedReadyRead) {
951 emittedReadyRead = true;
952 emit q->readyRead();
953 emittedReadyRead = false;
954 }
955 }
956 emit q->readyReadStandardError();
957 return didRead;
958}
959
960/*! \internal
961*/
962bool QProcessPrivate::_q_canWrite()
963{
964 Q_Q(QProcess);
965 if (stdinChannel.notifier)
966 stdinChannel.notifier->setEnabled(false);
967
968 if (writeBuffer.isEmpty()) {
969#if defined QPROCESS_DEBUG
970 qDebug("QProcessPrivate::canWrite(), not writing anything (empty write buffer).");
971#endif
972 return false;
973 }
974
975 qint64 written = writeToStdin(writeBuffer.readPointer(),
976 writeBuffer.nextDataBlockSize());
977 if (written < 0) {
978 destroyPipe(stdinChannel.pipe);
979 processError = QProcess::WriteError;
980 q->setErrorString(QProcess::tr("Error writing to process"));
981#if defined(QPROCESS_DEBUG) && !defined(Q_OS_WINCE)
982 qDebug("QProcessPrivate::canWrite(), failed to write (%s)", strerror(errno));
983#endif
984 emit q->error(processError);
985 return false;
986 }
987
988#if defined QPROCESS_DEBUG
989 qDebug("QProcessPrivate::canWrite(), wrote %d bytes to the process input", int(written));
990#endif
991
992 writeBuffer.free(written);
993 if (!emittedBytesWritten) {
994 emittedBytesWritten = true;
995 emit q->bytesWritten(written);
996 emittedBytesWritten = false;
997 }
998 if (stdinChannel.notifier && !writeBuffer.isEmpty())
999 stdinChannel.notifier->setEnabled(true);
1000 if (writeBuffer.isEmpty() && stdinChannel.closed)
1001 closeWriteChannel();
1002 return true;
1003}
1004
1005/*! \internal
1006*/
1007bool QProcessPrivate::_q_processDied()
1008{
1009 Q_Q(QProcess);
1010#if defined QPROCESS_DEBUG
1011 qDebug("QProcessPrivate::_q_processDied()");
1012#endif
1013#if defined(Q_OS_UNIX) || defined(Q_OS_OS2)
1014 if (!waitForDeadChild())
1015 return false;
1016#endif
1017#ifdef Q_OS_WIN
1018 if (processFinishedNotifier)
1019 processFinishedNotifier->setEnabled(false);
1020#endif
1021
1022 // the process may have died before it got a chance to report that it was
1023 // either running or stopped, so we will call _q_startupNotification() and
1024 // give it a chance to emit started() or error(FailedToStart).
1025 if (processState == QProcess::Starting) {
1026 if (!_q_startupNotification())
1027 return true;
1028 }
1029
1030 if (dying) {
1031 // at this point we know the process is dead. prevent
1032 // reentering this slot recursively by calling waitForFinished()
1033 // or opening a dialog inside slots connected to the readyRead
1034 // signals emitted below.
1035 return true;
1036 }
1037 dying = true;
1038
1039 // in case there is data in the pipe line and this slot by chance
1040 // got called before the read notifications, call these two slots
1041 // so the data is made available before the process dies.
1042 _q_canReadStandardOutput();
1043 _q_canReadStandardError();
1044
1045 findExitCode();
1046
1047 if (crashed) {
1048 exitStatus = QProcess::CrashExit;
1049 processError = QProcess::Crashed;
1050 q->setErrorString(QProcess::tr("Process crashed"));
1051 emit q->error(processError);
1052 }
1053
1054 bool wasRunning = (processState == QProcess::Running);
1055
1056 cleanup();
1057
1058 if (wasRunning) {
1059 // we received EOF now:
1060 emit q->readChannelFinished();
1061 // in the future:
1062 //emit q->standardOutputClosed();
1063 //emit q->standardErrorClosed();
1064
1065 emit q->finished(exitCode);
1066 emit q->finished(exitCode, exitStatus);
1067 }
1068#if defined QPROCESS_DEBUG
1069 qDebug("QProcessPrivate::_q_processDied() process is dead");
1070#endif
1071 return true;
1072}
1073
1074/*! \internal
1075*/
1076bool QProcessPrivate::_q_startupNotification()
1077{
1078 Q_Q(QProcess);
1079#if defined QPROCESS_DEBUG
1080 qDebug("QProcessPrivate::startupNotification()");
1081#endif
1082
1083 if (startupSocketNotifier)
1084 startupSocketNotifier->setEnabled(false);
1085 if (processStarted()) {
1086 q->setProcessState(QProcess::Running);
1087 emit q->started();
1088 return true;
1089 }
1090
1091 q->setProcessState(QProcess::NotRunning);
1092 processError = QProcess::FailedToStart;
1093 emit q->error(processError);
1094#if defined(Q_OS_UNIX) || defined(Q_OS_OS2)
1095 // make sure the process manager removes this entry
1096 waitForDeadChild();
1097 findExitCode();
1098#endif
1099 cleanup();
1100 return false;
1101}
1102
1103/*! \internal
1104*/
1105void QProcessPrivate::closeWriteChannel()
1106{
1107#if defined QPROCESS_DEBUG
1108 qDebug("QProcessPrivate::closeWriteChannel()");
1109#endif
1110 if (stdinChannel.notifier) {
1111 extern void qDeleteInEventHandler(QObject *o);
1112 stdinChannel.notifier->setEnabled(false);
1113 if (stdinChannel.notifier) {
1114 qDeleteInEventHandler(stdinChannel.notifier);
1115 stdinChannel.notifier = 0;
1116 }
1117 }
1118#ifdef Q_OS_WIN
1119 // ### Find a better fix, feeding the process little by little
1120 // instead.
1121 flushPipeWriter();
1122#endif
1123 destroyPipe(stdinChannel.pipe);
1124}
1125
1126/*!
1127 Constructs a QProcess object with the given \a parent.
1128*/
1129QProcess::QProcess(QObject *parent)
1130 : QIODevice(*new QProcessPrivate, parent)
1131{
1132#if defined QPROCESS_DEBUG
1133 qDebug("QProcess::QProcess(%p)", parent);
1134#endif
1135}
1136
1137/*!
1138 Destructs the QProcess object, i.e., killing the process.
1139
1140 Note that this function will not return until the process is
1141 terminated.
1142*/
1143QProcess::~QProcess()
1144{
1145 Q_D(QProcess);
1146 if (d->processState != NotRunning) {
1147 qWarning("QProcess: Destroyed while process is still running.");
1148 kill();
1149 waitForFinished();
1150 }
1151#if defined(Q_OS_UNIX) || defined(Q_OS_OS2)
1152 // make sure the process manager removes this entry
1153 d->findExitCode();
1154#endif
1155 d->cleanup();
1156}
1157
1158/*!
1159 \obsolete
1160 Returns the read channel mode of the QProcess. This function is
1161 equivalent to processChannelMode()
1162
1163 \sa processChannelMode()
1164*/
1165QProcess::ProcessChannelMode QProcess::readChannelMode() const
1166{
1167 return processChannelMode();
1168}
1169
1170/*!
1171 \obsolete
1172
1173 Use setProcessChannelMode(\a mode) instead.
1174
1175 \sa setProcessChannelMode()
1176*/
1177void QProcess::setReadChannelMode(ProcessChannelMode mode)
1178{
1179 setProcessChannelMode(mode);
1180}
1181
1182/*!
1183 \since 4.2
1184
1185 Returns the channel mode of the QProcess standard output and
1186 standard error channels.
1187
1188 \sa setProcessChannelMode(), ProcessChannelMode, setReadChannel()
1189*/
1190QProcess::ProcessChannelMode QProcess::processChannelMode() const
1191{
1192 Q_D(const QProcess);
1193 return d->processChannelMode;
1194}
1195
1196/*!
1197 \since 4.2
1198
1199 Sets the channel mode of the QProcess standard output and standard
1200 error channels to the \a mode specified.
1201 This mode will be used the next time start() is called. For example:
1202
1203 \snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 0
1204
1205 \sa processChannelMode(), ProcessChannelMode, setReadChannel()
1206*/
1207void QProcess::setProcessChannelMode(ProcessChannelMode mode)
1208{
1209 Q_D(QProcess);
1210 d->processChannelMode = mode;
1211}
1212
1213/*!
1214 Returns the current read channel of the QProcess.
1215
1216 \sa setReadChannel()
1217*/
1218QProcess::ProcessChannel QProcess::readChannel() const
1219{
1220 Q_D(const QProcess);
1221 return d->processChannel;
1222}
1223
1224/*!
1225 Sets the current read channel of the QProcess to the given \a
1226 channel. The current input channel is used by the functions
1227 read(), readAll(), readLine(), and getChar(). It also determines
1228 which channel triggers QProcess to emit readyRead().
1229
1230 \sa readChannel()
1231*/
1232void QProcess::setReadChannel(ProcessChannel channel)
1233{
1234 Q_D(QProcess);
1235 if (d->processChannel != channel) {
1236 QByteArray buf = d->buffer.readAll();
1237 if (d->processChannel == QProcess::StandardOutput) {
1238 for (int i = buf.size() - 1; i >= 0; --i)
1239 d->outputReadBuffer.ungetChar(buf.at(i));
1240 } else {
1241 for (int i = buf.size() - 1; i >= 0; --i)
1242 d->errorReadBuffer.ungetChar(buf.at(i));
1243 }
1244 }
1245 d->processChannel = channel;
1246}
1247
1248/*!
1249 Closes the read channel \a channel. After calling this function,
1250 QProcess will no longer receive data on the channel. Any data that
1251 has already been received is still available for reading.
1252
1253 Call this function to save memory, if you are not interested in
1254 the output of the process.
1255
1256 \sa closeWriteChannel(), setReadChannel()
1257*/
1258void QProcess::closeReadChannel(ProcessChannel channel)
1259{
1260 Q_D(QProcess);
1261
1262 if (channel == StandardOutput)
1263 d->stdoutChannel.closed = true;
1264 else
1265 d->stderrChannel.closed = true;
1266}
1267
1268/*!
1269 Schedules the write channel of QProcess to be closed. The channel
1270 will close once all data has been written to the process. After
1271 calling this function, any attempts to write to the process will
1272 fail.
1273
1274 Closing the write channel is necessary for programs that read
1275 input data until the channel has been closed. For example, the
1276 program "more" is used to display text data in a console on both
1277 Unix and Windows. But it will not display the text data until
1278 QProcess's write channel has been closed. Example:
1279
1280 \snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 1
1281
1282 The write channel is implicitly opened when start() is called.
1283
1284 \sa closeReadChannel()
1285*/
1286void QProcess::closeWriteChannel()
1287{
1288 Q_D(QProcess);
1289 d->stdinChannel.closed = true; // closing
1290 if (d->writeBuffer.isEmpty())
1291 d->closeWriteChannel();
1292}
1293
1294/*!
1295 \since 4.2
1296
1297 Redirects the process' standard input to the file indicated by \a
1298 fileName. When an input redirection is in place, the QProcess
1299 object will be in read-only mode (calling write() will result in
1300 error).
1301
1302 If the file \a fileName does not exist at the moment start() is
1303 called or is not readable, starting the process will fail.
1304
1305 Calling setStandardInputFile() after the process has started has no
1306 effect.
1307
1308 \sa setStandardOutputFile(), setStandardErrorFile(),
1309 setStandardOutputProcess()
1310*/
1311void QProcess::setStandardInputFile(const QString &fileName)
1312{
1313 Q_D(QProcess);
1314 d->stdinChannel = fileName;
1315}
1316
1317/*!
1318 \since 4.2
1319
1320 Redirects the process' standard output to the file \a
1321 fileName. When the redirection is in place, the standard output
1322 read channel is closed: reading from it using read() will always
1323 fail, as will readAllStandardOutput().
1324
1325 If the file \a fileName doesn't exist at the moment start() is
1326 called, it will be created. If it cannot be created, the starting
1327 will fail.
1328
1329 If the file exists and \a mode is QIODevice::Truncate, the file
1330 will be truncated. Otherwise (if \a mode is QIODevice::Append),
1331 the file will be appended to.
1332
1333 Calling setStandardOutputFile() after the process has started has
1334 no effect.
1335
1336 \sa setStandardInputFile(), setStandardErrorFile(),
1337 setStandardOutputProcess()
1338*/
1339void QProcess::setStandardOutputFile(const QString &fileName, OpenMode mode)
1340{
1341 Q_ASSERT(mode == Append || mode == Truncate);
1342 Q_D(QProcess);
1343
1344 d->stdoutChannel = fileName;
1345 d->stdoutChannel.append = mode == Append;
1346}
1347
1348/*!
1349 \since 4.2
1350
1351 Redirects the process' standard error to the file \a
1352 fileName. When the redirection is in place, the standard error
1353 read channel is closed: reading from it using read() will always
1354 fail, as will readAllStandardError(). The file will be appended to
1355 if \a mode is Append, otherwise, it will be truncated.
1356
1357 See setStandardOutputFile() for more information on how the file
1358 is opened.
1359
1360 Note: if setProcessChannelMode() was called with an argument of
1361 QProcess::MergedChannels, this function has no effect.
1362
1363 \sa setStandardInputFile(), setStandardOutputFile(),
1364 setStandardOutputProcess()
1365*/
1366void QProcess::setStandardErrorFile(const QString &fileName, OpenMode mode)
1367{
1368 Q_ASSERT(mode == Append || mode == Truncate);
1369 Q_D(QProcess);
1370
1371 d->stderrChannel = fileName;
1372 d->stderrChannel.append = mode == Append;
1373}
1374
1375/*!
1376 \since 4.2
1377
1378 Pipes the standard output stream of this process to the \a
1379 destination process' standard input.
1380
1381 The following shell command:
1382 \snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 2
1383
1384 Can be accomplished with QProcesses with the following code:
1385 \snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 3
1386*/
1387void QProcess::setStandardOutputProcess(QProcess *destination)
1388{
1389 QProcessPrivate *dfrom = d_func();
1390 QProcessPrivate *dto = destination->d_func();
1391 dfrom->stdoutChannel.pipeTo(dto);
1392 dto->stdinChannel.pipeFrom(dfrom);
1393}
1394
1395/*!
1396 If QProcess has been assigned a working directory, this function returns
1397 the working directory that the QProcess will enter before the program has
1398 started. Otherwise, (i.e., no directory has been assigned,) an empty
1399 string is returned, and QProcess will use the application's current
1400 working directory instead.
1401
1402 \sa setWorkingDirectory()
1403*/
1404QString QProcess::workingDirectory() const
1405{
1406 Q_D(const QProcess);
1407 return d->workingDirectory;
1408}
1409
1410/*!
1411 Sets the working directory to \a dir. QProcess will start the
1412 process in this directory. The default behavior is to start the
1413 process in the working directory of the calling process.
1414
1415 \note The working directory setting is ignored on Symbian;
1416 the private directory of the process is considered its working
1417 directory.
1418
1419 \sa workingDirectory(), start()
1420*/
1421void QProcess::setWorkingDirectory(const QString &dir)
1422{
1423 Q_D(QProcess);
1424 d->workingDirectory = dir;
1425}
1426
1427/*!
1428 Returns the native process identifier for the running process, if
1429 available. If no process is currently running, 0 is returned.
1430*/
1431Q_PID QProcess::pid() const
1432{
1433 Q_D(const QProcess);
1434 return d->pid;
1435}
1436
1437/*! \reimp
1438
1439 This function operates on the current read channel.
1440
1441 \sa readChannel(), setReadChannel()
1442*/
1443bool QProcess::canReadLine() const
1444{
1445 Q_D(const QProcess);
1446 const QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError)
1447 ? &d->errorReadBuffer
1448 : &d->outputReadBuffer;
1449 return readBuffer->canReadLine() || QIODevice::canReadLine();
1450}
1451
1452/*!
1453 Closes all communication with the process and kills it. After calling this
1454 function, QProcess will no longer emit readyRead(), and data can no
1455 longer be read or written.
1456*/
1457void QProcess::close()
1458{
1459 emit aboutToClose();
1460 while (waitForBytesWritten(-1))
1461 ;
1462 kill();
1463 waitForFinished(-1);
1464 QIODevice::close();
1465}
1466
1467/*! \reimp
1468
1469 Returns true if the process is not running, and no more data is available
1470 for reading; otherwise returns false.
1471*/
1472bool QProcess::atEnd() const
1473{
1474 Q_D(const QProcess);
1475 const QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError)
1476 ? &d->errorReadBuffer
1477 : &d->outputReadBuffer;
1478 return QIODevice::atEnd() && (!isOpen() || readBuffer->isEmpty());
1479}
1480
1481/*! \reimp
1482*/
1483bool QProcess::isSequential() const
1484{
1485 return true;
1486}
1487
1488/*! \reimp
1489*/
1490qint64 QProcess::bytesAvailable() const
1491{
1492 Q_D(const QProcess);
1493 const QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError)
1494 ? &d->errorReadBuffer
1495 : &d->outputReadBuffer;
1496#if defined QPROCESS_DEBUG
1497 qDebug("QProcess::bytesAvailable() == %i (%s)", readBuffer->size(),
1498 (d->processChannel == QProcess::StandardError) ? "stderr" : "stdout");
1499#endif
1500 return readBuffer->size() + QIODevice::bytesAvailable();
1501}
1502
1503/*! \reimp
1504*/
1505qint64 QProcess::bytesToWrite() const
1506{
1507 Q_D(const QProcess);
1508 qint64 size = d->writeBuffer.size();
1509#ifdef Q_OS_WIN
1510 size += d->pipeWriterBytesToWrite();
1511#endif
1512 return size;
1513}
1514
1515/*!
1516 Returns the type of error that occurred last.
1517
1518 \sa state()
1519*/
1520QProcess::ProcessError QProcess::error() const
1521{
1522 Q_D(const QProcess);
1523 return d->processError;
1524}
1525
1526/*!
1527 Returns the current state of the process.
1528
1529 \sa stateChanged(), error()
1530*/
1531QProcess::ProcessState QProcess::state() const
1532{
1533 Q_D(const QProcess);
1534 return d->processState;
1535}
1536
1537/*!
1538 \deprecated
1539 Sets the environment that QProcess will use when starting a process to the
1540 \a environment specified which consists of a list of key=value pairs.
1541
1542 For example, the following code adds the \c{C:\\BIN} directory to the list of
1543 executable paths (\c{PATHS}) on Windows:
1544
1545 \snippet doc/src/snippets/qprocess-environment/main.cpp 0
1546
1547 \note This function is less efficient than the setProcessEnvironment()
1548 function.
1549
1550 \sa environment(), setProcessEnvironment(), systemEnvironment()
1551*/
1552void QProcess::setEnvironment(const QStringList &environment)
1553{
1554 setProcessEnvironment(QProcessEnvironmentPrivate::fromList(environment));
1555}
1556
1557/*!
1558 \deprecated
1559 Returns the environment that QProcess will use when starting a
1560 process, or an empty QStringList if no environment has been set
1561 using setEnvironment() or setEnvironmentHash(). If no environment
1562 has been set, the environment of the calling process will be used.
1563
1564 \note The environment settings are ignored on Windows CE and Symbian,
1565 as there is no concept of an environment.
1566
1567 \sa processEnvironment(), setEnvironment(), systemEnvironment()
1568*/
1569QStringList QProcess::environment() const
1570{
1571 Q_D(const QProcess);
1572 return d->environment.toStringList();
1573}
1574
1575/*!
1576 \since 4.6
1577 Sets the environment that QProcess will use when starting a process to the
1578 \a environment object.
1579
1580 For example, the following code adds the \c{C:\\BIN} directory to the list of
1581 executable paths (\c{PATHS}) on Windows and sets \c{TMPDIR}:
1582
1583 \snippet doc/src/snippets/qprocess-environment/main.cpp 1
1584
1585 Note how, on Windows, environment variable names are case-insensitive.
1586
1587 \sa processEnvironment(), QProcessEnvironment::systemEnvironment(), setEnvironment()
1588*/
1589void QProcess::setProcessEnvironment(const QProcessEnvironment &environment)
1590{
1591 Q_D(QProcess);
1592 d->environment = environment;
1593}
1594
1595/*!
1596 \since 4.6
1597 Returns the environment that QProcess will use when starting a
1598 process, or an empty object if no environment has been set using
1599 setEnvironment() or setProcessEnvironment(). If no environment has
1600 been set, the environment of the calling process will be used.
1601
1602 \note The environment settings are ignored on Windows CE,
1603 as there is no concept of an environment.
1604
1605 \sa setProcessEnvironment(), setEnvironment(), QProcessEnvironment::isEmpty()
1606*/
1607QProcessEnvironment QProcess::processEnvironment() const
1608{
1609 Q_D(const QProcess);
1610 return d->environment;
1611}
1612
1613/*!
1614 Blocks until the process has started and the started() signal has
1615 been emitted, or until \a msecs milliseconds have passed.
1616
1617 Returns true if the process was started successfully; otherwise
1618 returns false (if the operation timed out or if an error
1619 occurred).
1620
1621 This function can operate without an event loop. It is
1622 useful when writing non-GUI applications and when performing
1623 I/O operations in a non-GUI thread.
1624
1625 \warning Calling this function from the main (GUI) thread
1626 might cause your user interface to freeze.
1627
1628 If msecs is -1, this function will not time out.
1629
1630 \sa started(), waitForReadyRead(), waitForBytesWritten(), waitForFinished()
1631*/
1632bool QProcess::waitForStarted(int msecs)
1633{
1634 Q_D(QProcess);
1635 if (d->processState == QProcess::Starting) {
1636 if (!d->waitForStarted(msecs))
1637 return false;
1638 setProcessState(QProcess::Running);
1639 emit started();
1640 }
1641 return d->processState == QProcess::Running;
1642}
1643
1644/*! \reimp
1645*/
1646bool QProcess::waitForReadyRead(int msecs)
1647{
1648 Q_D(QProcess);
1649
1650 if (d->processState == QProcess::NotRunning)
1651 return false;
1652 if (d->processChannel == QProcess::StandardOutput && d->stdoutChannel.closed)
1653 return false;
1654 if (d->processChannel == QProcess::StandardError && d->stderrChannel.closed)
1655 return false;
1656 return d->waitForReadyRead(msecs);
1657}
1658
1659/*! \reimp
1660*/
1661bool QProcess::waitForBytesWritten(int msecs)
1662{
1663 Q_D(QProcess);
1664 if (d->processState == QProcess::NotRunning)
1665 return false;
1666 if (d->processState == QProcess::Starting) {
1667 QTime stopWatch;
1668 stopWatch.start();
1669 bool started = waitForStarted(msecs);
1670 if (!started)
1671 return false;
1672 if (msecs != -1)
1673 msecs -= stopWatch.elapsed();
1674 }
1675
1676 return d->waitForBytesWritten(msecs);
1677}
1678
1679/*!
1680 Blocks until the process has finished and the finished() signal
1681 has been emitted, or until \a msecs milliseconds have passed.
1682
1683 Returns true if the process finished; otherwise returns false (if
1684 the operation timed out, if an error occurred, or if this QProcess
1685 is already finished).
1686
1687 This function can operate without an event loop. It is
1688 useful when writing non-GUI applications and when performing
1689 I/O operations in a non-GUI thread.
1690
1691 \warning Calling this function from the main (GUI) thread
1692 might cause your user interface to freeze.
1693
1694 If msecs is -1, this function will not time out.
1695
1696 \sa finished(), waitForStarted(), waitForReadyRead(), waitForBytesWritten()
1697*/
1698bool QProcess::waitForFinished(int msecs)
1699{
1700 Q_D(QProcess);
1701 if (d->processState == QProcess::NotRunning)
1702 return false;
1703 if (d->processState == QProcess::Starting) {
1704 QTime stopWatch;
1705 stopWatch.start();
1706 bool started = waitForStarted(msecs);
1707 if (!started)
1708 return false;
1709 if (msecs != -1)
1710 msecs -= stopWatch.elapsed();
1711 }
1712
1713 return d->waitForFinished(msecs);
1714}
1715
1716/*!
1717 Sets the current state of the QProcess to the \a state specified.
1718
1719 \sa state()
1720*/
1721void QProcess::setProcessState(ProcessState state)
1722{
1723 Q_D(QProcess);
1724 if (d->processState == state)
1725 return;
1726 d->processState = state;
1727 emit stateChanged(state);
1728}
1729
1730/*!
1731 This function is called in the child process context just before the
1732 program is executed on Unix or Mac OS X (i.e., after \e fork(), but before
1733 \e execve()). Reimplement this function to do last minute initialization
1734 of the child process. Example:
1735
1736 \snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 4
1737
1738 You cannot exit the process (by calling exit(), for instance) from
1739 this function. If you need to stop the program before it starts
1740 execution, your workaround is to emit finished() and then call
1741 exit().
1742
1743 \warning This function is called by QProcess on Unix and Mac OS X
1744 only. On Windows, it is not called.
1745*/
1746void QProcess::setupChildProcess()
1747{
1748}
1749
1750/*! \reimp
1751*/
1752qint64 QProcess::readData(char *data, qint64 maxlen)
1753{
1754 Q_D(QProcess);
1755 QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError)
1756 ? &d->errorReadBuffer
1757 : &d->outputReadBuffer;
1758
1759 if (maxlen == 1 && !readBuffer->isEmpty()) {
1760 int c = readBuffer->getChar();
1761 if (c == -1) {
1762#if defined QPROCESS_DEBUG
1763 qDebug("QProcess::readData(%p \"%s\", %d) == -1",
1764 data, qt_prettyDebug(data, 1, maxlen).constData(), 1);
1765#endif
1766 return -1;
1767 }
1768 *data = (char) c;
1769#if defined QPROCESS_DEBUG
1770 qDebug("QProcess::readData(%p \"%s\", %d) == 1",
1771 data, qt_prettyDebug(data, 1, maxlen).constData(), 1);
1772#endif
1773 return 1;
1774 }
1775
1776 qint64 bytesToRead = qint64(qMin(readBuffer->size(), (int)maxlen));
1777 qint64 readSoFar = 0;
1778 while (readSoFar < bytesToRead) {
1779 const char *ptr = readBuffer->readPointer();
1780 int bytesToReadFromThisBlock = qMin<qint64>(bytesToRead - readSoFar,
1781 readBuffer->nextDataBlockSize());
1782 memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock);
1783 readSoFar += bytesToReadFromThisBlock;
1784 readBuffer->free(bytesToReadFromThisBlock);
1785 }
1786
1787#if defined QPROCESS_DEBUG
1788 qDebug("QProcess::readData(%p \"%s\", %lld) == %lld",
1789 data, qt_prettyDebug(data, readSoFar, 16).constData(), maxlen, readSoFar);
1790#endif
1791 if (!readSoFar && d->processState == QProcess::NotRunning)
1792 return -1; // EOF
1793 return readSoFar;
1794}
1795
1796/*! \reimp
1797*/
1798qint64 QProcess::writeData(const char *data, qint64 len)
1799{
1800 Q_D(QProcess);
1801
1802#if defined(Q_OS_WINCE)
1803 Q_UNUSED(data);
1804 Q_UNUSED(len);
1805 d->processError = QProcess::WriteError;
1806 setErrorString(tr("Error writing to process"));
1807 emit error(d->processError);
1808 return -1;
1809#endif
1810
1811 if (d->stdinChannel.closed) {
1812#if defined QPROCESS_DEBUG
1813 qDebug("QProcess::writeData(%p \"%s\", %lld) == 0 (write channel closing)",
1814 data, qt_prettyDebug(data, len, 16).constData(), len);
1815#endif
1816 return 0;
1817 }
1818
1819 if (len == 1) {
1820 d->writeBuffer.putChar(*data);
1821 if (d->stdinChannel.notifier)
1822 d->stdinChannel.notifier->setEnabled(true);
1823#if defined QPROCESS_DEBUG
1824 qDebug("QProcess::writeData(%p \"%s\", %lld) == 1 (written to buffer)",
1825 data, qt_prettyDebug(data, len, 16).constData(), len);
1826#endif
1827#if defined(Q_OS_OS2)
1828 // try to write some bytes (there may be space in the pipe)
1829 d->_q_canWrite();
1830#endif
1831 return 1;
1832 }
1833
1834 char *dest = d->writeBuffer.reserve(len);
1835 memcpy(dest, data, len);
1836 if (d->stdinChannel.notifier)
1837 d->stdinChannel.notifier->setEnabled(true);
1838#if defined QPROCESS_DEBUG
1839 qDebug("QProcess::writeData(%p \"%s\", %lld) == %lld (written to buffer)",
1840 data, qt_prettyDebug(data, len, 16).constData(), len, len);
1841#endif
1842#if defined(Q_OS_OS2)
1843 // try to write some bytes (there may be space in the pipe)
1844 d->_q_canWrite();
1845#endif
1846 return len;
1847}
1848
1849/*!
1850 Regardless of the current read channel, this function returns all
1851 data available from the standard output of the process as a
1852 QByteArray.
1853
1854 \sa readyReadStandardOutput(), readAllStandardError(), readChannel(), setReadChannel()
1855*/
1856QByteArray QProcess::readAllStandardOutput()
1857{
1858 ProcessChannel tmp = readChannel();
1859 setReadChannel(StandardOutput);
1860 QByteArray data = readAll();
1861 setReadChannel(tmp);
1862 return data;
1863}
1864
1865/*!
1866 Regardless of the current read channel, this function returns all
1867 data available from the standard error of the process as a
1868 QByteArray.
1869
1870 \sa readyReadStandardError(), readAllStandardOutput(), readChannel(), setReadChannel()
1871*/
1872QByteArray QProcess::readAllStandardError()
1873{
1874 ProcessChannel tmp = readChannel();
1875 setReadChannel(StandardError);
1876 QByteArray data = readAll();
1877 setReadChannel(tmp);
1878 return data;
1879}
1880
1881/*!
1882 Starts the program \a program in a new process, if one is not already
1883 running, passing the command line arguments in \a arguments. The OpenMode
1884 is set to \a mode.
1885
1886 The QProcess object will immediately enter the Starting state. If the
1887 process starts successfully, QProcess will emit started(); otherwise,
1888 error() will be emitted. If the QProcess object is already running a
1889 process, a warning may be printed at the console, and the existing
1890 process will continue running.
1891
1892 \note Arguments that contain spaces are not passed to the
1893 process as separate arguments.
1894
1895 \note Processes are started asynchronously, which means the started()
1896 and error() signals may be delayed. Call waitForStarted() to make
1897 sure the process has started (or has failed to start) and those signals
1898 have been emitted.
1899
1900 \bold{Windows:} Arguments that contain spaces are wrapped in quotes.
1901
1902 \sa pid(), started(), waitForStarted()
1903*/
1904void QProcess::start(const QString &program, const QStringList &arguments, OpenMode mode)
1905{
1906 Q_D(QProcess);
1907 if (d->processState != NotRunning) {
1908 qWarning("QProcess::start: Process is already running");
1909 return;
1910 }
1911
1912#if defined QPROCESS_DEBUG
1913 qDebug() << "QProcess::start(" << program << ',' << arguments << ',' << mode << ')';
1914#endif
1915
1916 d->outputReadBuffer.clear();
1917 d->errorReadBuffer.clear();
1918
1919 if (d->stdinChannel.type != QProcessPrivate::Channel::Normal)
1920 mode &= ~WriteOnly; // not open for writing
1921 if (d->stdoutChannel.type != QProcessPrivate::Channel::Normal &&
1922 (d->stderrChannel.type != QProcessPrivate::Channel::Normal ||
1923 d->processChannelMode == MergedChannels))
1924 mode &= ~ReadOnly; // not open for reading
1925 if (mode == 0)
1926 mode = Unbuffered;
1927 QIODevice::open(mode);
1928
1929 d->stdinChannel.closed = false;
1930 d->stdoutChannel.closed = false;
1931 d->stderrChannel.closed = false;
1932
1933 d->program = program;
1934 d->arguments = arguments;
1935
1936 d->exitCode = 0;
1937 d->exitStatus = NormalExit;
1938 d->processError = QProcess::UnknownError;
1939 d->errorString.clear();
1940 d->startProcess();
1941}
1942
1943
1944static QStringList parseCombinedArgString(const QString &program)
1945{
1946 QStringList args;
1947 QString tmp;
1948 int quoteCount = 0;
1949 bool inQuote = false;
1950
1951 // handle quoting. tokens can be surrounded by double quotes
1952 // "hello world". three consecutive double quotes represent
1953 // the quote character itself.
1954 for (int i = 0; i < program.size(); ++i) {
1955 if (program.at(i) == QLatin1Char('"')) {
1956 ++quoteCount;
1957 if (quoteCount == 3) {
1958 // third consecutive quote
1959 quoteCount = 0;
1960 tmp += program.at(i);
1961 }
1962 continue;
1963 }
1964 if (quoteCount) {
1965 if (quoteCount == 1)
1966 inQuote = !inQuote;
1967 quoteCount = 0;
1968 }
1969 if (!inQuote && program.at(i).isSpace()) {
1970 if (!tmp.isEmpty()) {
1971 args += tmp;
1972 tmp.clear();
1973 }
1974 } else {
1975 tmp += program.at(i);
1976 }
1977 }
1978 if (!tmp.isEmpty())
1979 args += tmp;
1980
1981 return args;
1982}
1983
1984/*!
1985 \overload
1986
1987 Starts the program \a program in a new process, if one is not already
1988 running. \a program is a single string of text containing both the
1989 program name and its arguments. The arguments are separated by one or
1990 more spaces. For example:
1991
1992 \snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 5
1993
1994 The \a program string can also contain quotes, to ensure that arguments
1995 containing spaces are correctly supplied to the new process. For example:
1996
1997 \snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 6
1998
1999 If the QProcess object is already running a process, a warning may be
2000 printed at the console, and the existing process will continue running.
2001
2002 Note that, on Windows, quotes need to be both escaped and quoted.
2003 For example, the above code would be specified in the following
2004 way to ensure that \c{"My Documents"} is used as the argument to
2005 the \c dir executable:
2006
2007 \snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 7
2008
2009 The OpenMode is set to \a mode.
2010*/
2011void QProcess::start(const QString &program, OpenMode mode)
2012{
2013 QStringList args = parseCombinedArgString(program);
2014 if (args.isEmpty()) {
2015 Q_D(QProcess);
2016 d->processError = QProcess::FailedToStart;
2017 setErrorString(tr("No program defined"));
2018 emit error(d->processError);
2019 return;
2020 }
2021
2022 QString prog = args.first();
2023 args.removeFirst();
2024
2025 start(prog, args, mode);
2026}
2027
2028/*!
2029 Attempts to terminate the process.
2030
2031 The process may not exit as a result of calling this function (it is given
2032 the chance to prompt the user for any unsaved files, etc).
2033
2034 On Windows, terminate() posts a WM_CLOSE message to all toplevel windows
2035 of the process and then to the main thread of the process itself. On Unix
2036 and Mac OS X the SIGTERM signal is sent.
2037
2038 Console applications on Windows that do not run an event loop, or whose
2039 event loop does not handle the WM_CLOSE message, can only be terminated by
2040 calling kill().
2041
2042 On Symbian, this function requires platform security capability
2043 \c PowerMgmt. If absent, the process will panic with KERN-EXEC 46.
2044
2045 \note Terminating running processes from other processes will typically
2046 cause a panic in Symbian due to platform security.
2047
2048 \sa \l {Symbian Platform Security Requirements}
2049 \sa kill()
2050*/
2051void QProcess::terminate()
2052{
2053 Q_D(QProcess);
2054 d->terminateProcess();
2055}
2056
2057/*!
2058 Kills the current process, causing it to exit immediately.
2059
2060 On Windows, kill() uses TerminateProcess, and on Unix and Mac OS X, the
2061 SIGKILL signal is sent to the process.
2062
2063 On Symbian, this function requires platform security capability
2064 \c PowerMgmt. If absent, the process will panic with KERN-EXEC 46.
2065
2066 \sa \l {Symbian Platform Security Requirements}
2067 \sa terminate()
2068*/
2069void QProcess::kill()
2070{
2071 Q_D(QProcess);
2072 d->killProcess();
2073}
2074
2075/*!
2076 Returns the exit code of the last process that finished.
2077*/
2078int QProcess::exitCode() const
2079{
2080 Q_D(const QProcess);
2081 return d->exitCode;
2082}
2083
2084/*!
2085 \since 4.1
2086
2087 Returns the exit status of the last process that finished.
2088
2089 On Windows, if the process was terminated with TerminateProcess()
2090 from another application this function will still return NormalExit
2091 unless the exit code is less than 0.
2092*/
2093QProcess::ExitStatus QProcess::exitStatus() const
2094{
2095 Q_D(const QProcess);
2096 return d->exitStatus;
2097}
2098
2099/*!
2100 Starts the program \a program with the arguments \a arguments in a
2101 new process, waits for it to finish, and then returns the exit
2102 code of the process. Any data the new process writes to the
2103 console is forwarded to the calling process.
2104
2105 The environment and working directory are inherited by the calling
2106 process.
2107
2108 On Windows, arguments that contain spaces are wrapped in quotes.
2109*/
2110int QProcess::execute(const QString &program, const QStringList &arguments)
2111{
2112 QProcess process;
2113 process.setReadChannelMode(ForwardedChannels);
2114 process.start(program, arguments);
2115 process.waitForFinished(-1);
2116 return process.exitCode();
2117}
2118
2119/*!
2120 \overload
2121
2122 Starts the program \a program in a new process. \a program is a
2123 single string of text containing both the program name and its
2124 arguments. The arguments are separated by one or more spaces.
2125*/
2126int QProcess::execute(const QString &program)
2127{
2128 QProcess process;
2129 process.setReadChannelMode(ForwardedChannels);
2130 process.start(program);
2131 process.waitForFinished(-1);
2132 return process.exitCode();
2133}
2134
2135/*!
2136 Starts the program \a program with the arguments \a arguments in a
2137 new process, and detaches from it. Returns true on success;
2138 otherwise returns false. If the calling process exits, the
2139 detached process will continue to live.
2140
2141 Note that arguments that contain spaces are not passed to the
2142 process as separate arguments.
2143
2144 \bold{Unix:} The started process will run in its own session and act
2145 like a daemon.
2146
2147 \bold{Windows:} Arguments that contain spaces are wrapped in quotes.
2148 The started process will run as a regular standalone process.
2149
2150 \bold{OS/2:} The started process will run in its own session which is
2151 completely independent from the session of the starting application and
2152 will continue execution after the starting application terminates.
2153
2154 The process will be started in the directory \a workingDirectory.
2155
2156 If the function is successful then *\a pid is set to the process
2157 identifier of the started process.
2158
2159 Note that on OS/2, the PID of the started process is unknown and the value
2160 returned in \a pid is always 0.
2161*/
2162bool QProcess::startDetached(const QString &program,
2163 const QStringList &arguments,
2164 const QString &workingDirectory,
2165 qint64 *pid)
2166{
2167 return QProcessPrivate::startDetached(program,
2168 arguments,
2169 workingDirectory,
2170 pid);
2171}
2172
2173/*!
2174 Starts the program \a program with the given \a arguments in a
2175 new process, and detaches from it. Returns true on success;
2176 otherwise returns false. If the calling process exits, the
2177 detached process will continue to live.
2178
2179 \note Arguments that contain spaces are not passed to the
2180 process as separate arguments.
2181
2182 \bold{Unix:} The started process will run in its own session and act
2183 like a daemon.
2184
2185 \bold{Windows:} Arguments that contain spaces are wrapped in quotes.
2186 The started process will run as a regular standalone process.
2187*/
2188bool QProcess::startDetached(const QString &program,
2189 const QStringList &arguments)
2190{
2191 return QProcessPrivate::startDetached(program, arguments);
2192}
2193
2194/*!
2195 \overload
2196
2197 Starts the program \a program in a new process. \a program is a
2198 single string of text containing both the program name and its
2199 arguments. The arguments are separated by one or more spaces.
2200
2201 The \a program string can also contain quotes, to ensure that arguments
2202 containing spaces are correctly supplied to the new process.
2203*/
2204bool QProcess::startDetached(const QString &program)
2205{
2206 QStringList args = parseCombinedArgString(program);
2207 if (args.isEmpty())
2208 return false;
2209
2210 QString prog = args.first();
2211 args.removeFirst();
2212
2213 return QProcessPrivate::startDetached(prog, args);
2214}
2215
2216QT_BEGIN_INCLUDE_NAMESPACE
2217#ifdef Q_OS_MAC
2218# include <crt_externs.h>
2219# define environ (*_NSGetEnviron())
2220#elif defined(Q_OS_WINCE) || defined(Q_OS_SYMBIAN)
2221 static char *qt_empty_environ[] = { 0 };
2222#define environ qt_empty_environ
2223#elif !defined(Q_OS_WIN)
2224 extern char **environ;
2225#endif
2226QT_END_INCLUDE_NAMESPACE
2227
2228/*!
2229 \since 4.1
2230
2231 Returns the environment of the calling process as a list of
2232 key=value pairs. Example:
2233
2234 \snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 8
2235
2236 This function does not cache the system environment. Therefore, it's
2237 possible to obtain an updated version of the environment if low-level C
2238 library functions like \tt setenv ot \tt putenv have been called.
2239
2240 However, note that repeated calls to this function will recreate the
2241 list of environment variables, which is a non-trivial operation.
2242
2243 \note For new code, it is recommended to use QProcessEvironment::systemEnvironment()
2244
2245 \sa QProcessEnvironment::systemEnvironment(), environment(), setEnvironment()
2246*/
2247QStringList QProcess::systemEnvironment()
2248{
2249 QStringList tmp;
2250 char *entry = 0;
2251 int count = 0;
2252 while ((entry = environ[count++]))
2253 tmp << QString::fromLocal8Bit(entry);
2254 return tmp;
2255}
2256
2257/*!
2258 \since 4.6
2259
2260 \brief The systemEnvironment function returns the environment of
2261 the calling process.
2262
2263 It is returned as a QProcessEnvironment. This function does not
2264 cache the system environment. Therefore, it's possible to obtain
2265 an updated version of the environment if low-level C library
2266 functions like \tt setenv ot \tt putenv have been called.
2267
2268 However, note that repeated calls to this function will recreate the
2269 QProcessEnvironment object, which is a non-trivial operation.
2270
2271 \sa QProcess::systemEnvironment()
2272*/
2273QProcessEnvironment QProcessEnvironment::systemEnvironment()
2274{
2275 QProcessEnvironment env;
2276 const char *entry;
2277 for (int count = 0; (entry = environ[count]); ++count) {
2278 const char *equal = strchr(entry, '=');
2279 if (!equal)
2280 continue;
2281
2282 QByteArray name(entry, equal - entry);
2283 QByteArray value(equal + 1);
2284 env.insert(QString::fromLocal8Bit(name), QString::fromLocal8Bit(value));
2285 }
2286 return env;
2287}
2288
2289/*!
2290 \typedef Q_PID
2291 \relates QProcess
2292
2293 Typedef for the identifiers used to represent processes on the underlying
2294 platform. On Unix and Symbian, this corresponds to \l qint64; on Windows, it
2295 corresponds to \c{_PROCESS_INFORMATION*}.
2296
2297 \sa QProcess::pid()
2298*/
2299
2300QT_END_NAMESPACE
2301
2302#include "moc_qprocess.cpp"
2303
2304#endif // QT_NO_PROCESS
2305
Note: See TracBrowser for help on using the repository browser.