1 | // Copyright (C) 2021 The Qt Company Ltd. |
2 | // Copyright (C) 2022 Intel Corporation. |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
4 | |
5 | //#define QPROCESS_DEBUG |
6 | |
7 | #include <qdebug.h> |
8 | #include <qdir.h> |
9 | #include <qscopedvaluerollback.h> |
10 | |
11 | #include "qprocess.h" |
12 | #include "qprocess_p.h" |
13 | |
14 | #include <qbytearray.h> |
15 | #include <qdeadlinetimer.h> |
16 | #include <qcoreapplication.h> |
17 | #include <qtimer.h> |
18 | |
19 | #if __has_include(<paths.h>) |
20 | #include <paths.h> |
21 | #endif |
22 | |
23 | QT_BEGIN_NAMESPACE |
24 | |
25 | /*! |
26 | \class QProcessEnvironment |
27 | \inmodule QtCore |
28 | |
29 | \brief The QProcessEnvironment class holds the environment variables that |
30 | can be passed to a program. |
31 | |
32 | \ingroup io |
33 | \ingroup misc |
34 | \ingroup shared |
35 | \reentrant |
36 | \since 4.6 |
37 | |
38 | \compares equality |
39 | |
40 | A process's environment is composed of a set of key=value pairs known as |
41 | environment variables. The QProcessEnvironment class wraps that concept |
42 | and allows easy manipulation of those variables. It's meant to be used |
43 | along with QProcess, to set the environment for child processes. It |
44 | cannot be used to change the current process's environment. |
45 | |
46 | The environment of the calling process can be obtained using |
47 | QProcessEnvironment::systemEnvironment(). |
48 | |
49 | On Unix systems, the variable names are case-sensitive. Note that the |
50 | Unix environment allows both variable names and contents to contain arbitrary |
51 | binary data (except for the NUL character). QProcessEnvironment will preserve |
52 | such variables, but does not support manipulating variables whose names or |
53 | values cannot be encoded by the current locale settings (see |
54 | QString::toLocal8Bit). |
55 | |
56 | On Windows, the variable names are case-insensitive, but case-preserving. |
57 | QProcessEnvironment behaves accordingly. |
58 | |
59 | \sa QProcess, QProcess::systemEnvironment(), QProcess::setProcessEnvironment() |
60 | */ |
61 | |
62 | QStringList QProcessEnvironmentPrivate::toList() const |
63 | { |
64 | QStringList result; |
65 | result.reserve(asize: vars.size()); |
66 | for (auto it = vars.cbegin(), end = vars.cend(); it != end; ++it) |
67 | result << nameToString(name: it.key()) + u'=' + valueToString(value: it.value()); |
68 | return result; |
69 | } |
70 | |
71 | QProcessEnvironment QProcessEnvironmentPrivate::fromList(const QStringList &list) |
72 | { |
73 | QProcessEnvironment env; |
74 | QStringList::ConstIterator it = list.constBegin(), |
75 | end = list.constEnd(); |
76 | for ( ; it != end; ++it) { |
77 | const qsizetype pos = it->indexOf(c: u'=', from: 1); |
78 | if (pos < 1) |
79 | continue; |
80 | |
81 | QString value = it->mid(position: pos + 1); |
82 | QString name = *it; |
83 | name.truncate(pos); |
84 | env.insert(name, value); |
85 | } |
86 | return env; |
87 | } |
88 | |
89 | QStringList QProcessEnvironmentPrivate::keys() const |
90 | { |
91 | QStringList result; |
92 | result.reserve(asize: vars.size()); |
93 | auto it = vars.constBegin(); |
94 | const auto end = vars.constEnd(); |
95 | for ( ; it != end; ++it) |
96 | result << nameToString(name: it.key()); |
97 | return result; |
98 | } |
99 | |
100 | void QProcessEnvironmentPrivate::insert(const QProcessEnvironmentPrivate &other) |
101 | { |
102 | auto it = other.vars.constBegin(); |
103 | const auto end = other.vars.constEnd(); |
104 | for ( ; it != end; ++it) |
105 | vars.insert(key: it.key(), value: it.value()); |
106 | |
107 | #ifdef Q_OS_UNIX |
108 | const OrderedNameMapMutexLocker locker(this, &other); |
109 | auto nit = other.nameMap.constBegin(); |
110 | const auto nend = other.nameMap.constEnd(); |
111 | for ( ; nit != nend; ++nit) |
112 | nameMap.insert(key: nit.key(), value: nit.value()); |
113 | #endif |
114 | } |
115 | |
116 | /*! |
117 | \enum QProcessEnvironment::Initialization |
118 | |
119 | This enum contains a token that is used to disambiguate constructors. |
120 | |
121 | \value InheritFromParent A QProcessEnvironment will be created that, when |
122 | set on a QProcess, causes it to inherit variables from its parent. |
123 | |
124 | \since 6.3 |
125 | */ |
126 | |
127 | /*! |
128 | Creates a new QProcessEnvironment object. This constructor creates an |
129 | empty environment. If set on a QProcess, this will cause the current |
130 | environment variables to be removed (except for PATH and SystemRoot |
131 | on Windows). |
132 | */ |
133 | QProcessEnvironment::QProcessEnvironment() : d(new QProcessEnvironmentPrivate) { } |
134 | |
135 | /*! |
136 | Creates an object that when set on QProcess will cause it to be executed with |
137 | environment variables inherited from its parent process. |
138 | |
139 | \note The created object does not store any environment variables by itself, |
140 | it just indicates to QProcess to arrange for inheriting the environment at the |
141 | time when the new process is started. Adding any environment variables to |
142 | the created object will disable inheritance of the environment and result in |
143 | an environment containing only the added environment variables. |
144 | |
145 | If a modified version of the parent environment is wanted, start with the |
146 | return value of \c systemEnvironment() and modify that (but note that changes to |
147 | the parent process's environment after that is created won't be reflected |
148 | in the modified environment). |
149 | |
150 | \sa inheritsFromParent(), systemEnvironment() |
151 | \since 6.3 |
152 | */ |
153 | QProcessEnvironment::QProcessEnvironment(QProcessEnvironment::Initialization) noexcept { } |
154 | |
155 | /*! |
156 | Frees the resources associated with this QProcessEnvironment object. |
157 | */ |
158 | QProcessEnvironment::~QProcessEnvironment() |
159 | { |
160 | } |
161 | |
162 | /*! |
163 | Creates a QProcessEnvironment object that is a copy of \a other. |
164 | */ |
165 | QProcessEnvironment::QProcessEnvironment(const QProcessEnvironment &other) |
166 | : d(other.d) |
167 | { |
168 | } |
169 | |
170 | /*! |
171 | Copies the contents of the \a other QProcessEnvironment object into this |
172 | one. |
173 | */ |
174 | QProcessEnvironment &QProcessEnvironment::operator=(const QProcessEnvironment &other) |
175 | { |
176 | d = other.d; |
177 | return *this; |
178 | } |
179 | |
180 | /*! |
181 | \fn void QProcessEnvironment::swap(QProcessEnvironment &other) |
182 | \since 5.0 |
183 | |
184 | Swaps this process environment instance with \a other. This |
185 | function is very fast and never fails. |
186 | */ |
187 | |
188 | /*! |
189 | \fn bool QProcessEnvironment::operator!=(const QProcessEnvironment &lhs, const QProcessEnvironment &rhs) |
190 | |
191 | Returns \c true if the process environment objects \a lhs and \a rhs are different. |
192 | |
193 | \sa operator==() |
194 | */ |
195 | |
196 | /*! |
197 | \fn bool QProcessEnvironment::operator==(const QProcessEnvironment &lhs, const QProcessEnvironment &rhs) |
198 | |
199 | Returns \c true if the process environment objects \a lhs and \a rhs are equal. |
200 | |
201 | Two QProcessEnvironment objects are considered equal if they have the same |
202 | set of key=value pairs. The comparison of keys is done case-sensitive on |
203 | platforms where the environment is case-sensitive. |
204 | |
205 | \sa operator!=(), contains() |
206 | */ |
207 | bool comparesEqual(const QProcessEnvironment &lhs, const QProcessEnvironment &rhs) |
208 | { |
209 | if (lhs.d == rhs.d) |
210 | return true; |
211 | |
212 | return lhs.d && rhs.d && lhs.d->vars == rhs.d->vars; |
213 | } |
214 | |
215 | /*! |
216 | Returns \c true if this QProcessEnvironment object is empty: that is |
217 | there are no key=value pairs set. |
218 | |
219 | This method also returns \c true for objects that were constructed using |
220 | \c{QProcessEnvironment::InheritFromParent}. |
221 | |
222 | \sa clear(), systemEnvironment(), insert(), inheritsFromParent() |
223 | */ |
224 | bool QProcessEnvironment::isEmpty() const |
225 | { |
226 | // Needs no locking, as no hash nodes are accessed |
227 | return d ? d->vars.isEmpty() : true; |
228 | } |
229 | |
230 | /*! |
231 | Returns \c true if this QProcessEnvironment was constructed using |
232 | \c{QProcessEnvironment::InheritFromParent}. |
233 | |
234 | \since 6.3 |
235 | \sa isEmpty() |
236 | */ |
237 | bool QProcessEnvironment::inheritsFromParent() const |
238 | { |
239 | return !d; |
240 | } |
241 | |
242 | /*! |
243 | Removes all key=value pairs from this QProcessEnvironment object, making |
244 | it empty. |
245 | |
246 | If the environment was constructed using \c{QProcessEnvironment::InheritFromParent} |
247 | it remains unchanged. |
248 | |
249 | \sa isEmpty(), systemEnvironment() |
250 | */ |
251 | void QProcessEnvironment::clear() |
252 | { |
253 | if (d.constData()) |
254 | d->vars.clear(); |
255 | // Unix: Don't clear d->nameMap, as the environment is likely to be |
256 | // re-populated with the same keys again. |
257 | } |
258 | |
259 | /*! |
260 | Returns \c true if the environment variable of name \a name is found in |
261 | this QProcessEnvironment object. |
262 | |
263 | |
264 | \sa insert(), value() |
265 | */ |
266 | bool QProcessEnvironment::contains(const QString &name) const |
267 | { |
268 | if (!d) |
269 | return false; |
270 | return d->vars.contains(key: d->prepareName(name)); |
271 | } |
272 | |
273 | /*! |
274 | Inserts the environment variable of name \a name and contents \a value |
275 | into this QProcessEnvironment object. If that variable already existed, |
276 | it is replaced by the new value. |
277 | |
278 | On most systems, inserting a variable with no contents will have the |
279 | same effect for applications as if the variable had not been set at all. |
280 | However, to guarantee that there are no incompatibilities, to remove a |
281 | variable, please use the remove() function. |
282 | |
283 | \sa contains(), remove(), value() |
284 | */ |
285 | void QProcessEnvironment::insert(const QString &name, const QString &value) |
286 | { |
287 | // our re-impl of detach() detaches from null |
288 | d.detach(); // detach before prepareName() |
289 | d->vars.insert(key: d->prepareName(name), value: d->prepareValue(value)); |
290 | } |
291 | |
292 | /*! |
293 | Removes the environment variable identified by \a name from this |
294 | QProcessEnvironment object. If that variable did not exist before, |
295 | nothing happens. |
296 | |
297 | |
298 | \sa contains(), insert(), value() |
299 | */ |
300 | void QProcessEnvironment::remove(const QString &name) |
301 | { |
302 | if (d.constData()) { |
303 | QProcessEnvironmentPrivate *p = d.data(); |
304 | p->vars.remove(key: p->prepareName(name)); |
305 | } |
306 | } |
307 | |
308 | /*! |
309 | Searches this QProcessEnvironment object for a variable identified by |
310 | \a name and returns its value. If the variable is not found in this object, |
311 | then \a defaultValue is returned instead. |
312 | |
313 | \sa contains(), insert(), remove() |
314 | */ |
315 | QString QProcessEnvironment::value(const QString &name, const QString &defaultValue) const |
316 | { |
317 | if (!d) |
318 | return defaultValue; |
319 | |
320 | const auto it = d->vars.constFind(key: d->prepareName(name)); |
321 | if (it == d->vars.constEnd()) |
322 | return defaultValue; |
323 | |
324 | return d->valueToString(value: it.value()); |
325 | } |
326 | |
327 | /*! |
328 | Converts this QProcessEnvironment object into a list of strings, one for |
329 | each environment variable that is set. The environment variable's name |
330 | and its value are separated by an equal character ('='). |
331 | |
332 | The QStringList contents returned by this function are suitable for |
333 | presentation. |
334 | Use with the QProcess::setEnvironment function is not recommended due to |
335 | potential encoding problems under Unix, and worse performance. |
336 | |
337 | \sa systemEnvironment(), QProcess::systemEnvironment(), |
338 | QProcess::setProcessEnvironment() |
339 | */ |
340 | QStringList QProcessEnvironment::toStringList() const |
341 | { |
342 | if (!d) |
343 | return QStringList(); |
344 | return d->toList(); |
345 | } |
346 | |
347 | /*! |
348 | \since 4.8 |
349 | |
350 | Returns a list containing all the variable names in this QProcessEnvironment |
351 | object. |
352 | |
353 | The returned list is empty for objects constructed using |
354 | \c{QProcessEnvironment::InheritFromParent}. |
355 | */ |
356 | QStringList QProcessEnvironment::keys() const |
357 | { |
358 | if (!d) |
359 | return QStringList(); |
360 | return d->keys(); |
361 | } |
362 | |
363 | /*! |
364 | \overload |
365 | \since 4.8 |
366 | |
367 | Inserts the contents of \a e in this QProcessEnvironment object. Variables in |
368 | this object that also exist in \a e will be overwritten. |
369 | */ |
370 | void QProcessEnvironment::insert(const QProcessEnvironment &e) |
371 | { |
372 | if (!e.d) |
373 | return; |
374 | |
375 | // our re-impl of detach() detaches from null |
376 | d->insert(other: *e.d); |
377 | } |
378 | |
379 | #if QT_CONFIG(process) |
380 | |
381 | void QProcessPrivate::Channel::clear() |
382 | { |
383 | switch (type) { |
384 | case PipeSource: |
385 | Q_ASSERT(process); |
386 | process->stdinChannel.type = Normal; |
387 | process->stdinChannel.process = nullptr; |
388 | break; |
389 | case PipeSink: |
390 | Q_ASSERT(process); |
391 | process->stdoutChannel.type = Normal; |
392 | process->stdoutChannel.process = nullptr; |
393 | break; |
394 | default: |
395 | break; |
396 | } |
397 | |
398 | type = Normal; |
399 | file.clear(); |
400 | process = nullptr; |
401 | } |
402 | |
403 | /*! |
404 | \class QProcess |
405 | \inmodule QtCore |
406 | |
407 | \brief The QProcess class is used to start external programs and |
408 | to communicate with them. |
409 | |
410 | \ingroup io |
411 | |
412 | \reentrant |
413 | |
414 | \section1 Running a Process |
415 | |
416 | To start a process, pass the name and command line arguments of |
417 | the program you want to run as arguments to start(). Arguments |
418 | are supplied as individual strings in a QStringList. |
419 | |
420 | Alternatively, you can set the program to run with setProgram() |
421 | and setArguments(), and then call start() or open(). |
422 | |
423 | For example, the following code snippet runs the analog clock |
424 | example in the Fusion style on X11 platforms by passing strings |
425 | containing "-style" and "fusion" as two items in the list of |
426 | arguments: |
427 | |
428 | \snippet qprocess/qprocess-simpleexecution.cpp 0 |
429 | \dots |
430 | \snippet qprocess/qprocess-simpleexecution.cpp 1 |
431 | \snippet qprocess/qprocess-simpleexecution.cpp 2 |
432 | |
433 | QProcess then enters the \l Starting state, and when the program |
434 | has started, QProcess enters the \l Running state and emits |
435 | started(). |
436 | |
437 | QProcess allows you to treat a process as a sequential I/O |
438 | device. You can write to and read from the process just as you |
439 | would access a network connection using QTcpSocket. You can then |
440 | write to the process's standard input by calling write(), and |
441 | read the standard output by calling read(), readLine(), and |
442 | getChar(). Because it inherits QIODevice, QProcess can also be |
443 | used as an input source for QXmlReader, or for generating data to |
444 | be uploaded using QNetworkAccessManager. |
445 | |
446 | When the process exits, QProcess reenters the \l NotRunning state |
447 | (the initial state), and emits finished(). |
448 | |
449 | The finished() signal provides the exit code and exit status of |
450 | the process as arguments, and you can also call exitCode() to |
451 | obtain the exit code of the last process that finished, and |
452 | exitStatus() to obtain its exit status. If an error occurs at |
453 | any point in time, QProcess will emit the errorOccurred() signal. |
454 | You can also call error() to find the type of error that occurred |
455 | last, and state() to find the current process state. |
456 | |
457 | \note QProcess is not supported on VxWorks, iOS, tvOS, or watchOS. |
458 | |
459 | \section1 Finding the Executable |
460 | |
461 | The program to be run can be set either by calling setProgram() or directly |
462 | in the start() call. The effect of calling start() with the program name |
463 | and arguments is equivalent to calling setProgram() and setArguments() |
464 | before that function and then calling the overload without those |
465 | parameters. |
466 | |
467 | QProcess interprets the program name in one of three different ways, |
468 | similar to how Unix shells and the Windows command interpreter operate in |
469 | their own command-lines: |
470 | |
471 | \list |
472 | \li If the program name is an absolute path, then that is the exact |
473 | executable that will be launched and QProcess performs no searching. |
474 | |
475 | \li If the program name is a relative path with more than one path |
476 | component (that is, it contains at least one slash), the starting |
477 | directory where that relative path is searched is OS-dependent: on |
478 | Windows, it's the parent process' current working dir, while on Unix it's |
479 | the one set with setWorkingDirectory(). |
480 | |
481 | \li If the program name is a plain file name with no slashes, the |
482 | behavior is operating-system dependent. On Unix systems, QProcess will |
483 | search the \c PATH environment variable; on Windows, the search is |
484 | performed by the OS and will first the parent process' current directory |
485 | before the \c PATH environment variable (see the documentation for |
486 | \l{CreateProcess} for the full list). |
487 | \endlist |
488 | |
489 | To avoid platform-dependent behavior or any issues with how the current |
490 | application was launched, it is advisable to always pass an absolute path |
491 | to the executable to be launched. For auxiliary binaries shipped with the |
492 | application, one can construct such a path starting with |
493 | QCoreApplication::applicationDirPath(). Similarly, to explicitly run an |
494 | executable that is to be found relative to the directory set with |
495 | setWorkingDirectory(), use a program path starting with "./" or "../" as |
496 | the case may be. |
497 | |
498 | On Windows, the ".exe" suffix is not required for most uses, except those |
499 | outlined in the \l{CreateProcess} documentation. Additionally, QProcess |
500 | will convert the Unix-style forward slashes to Windows path backslashes for |
501 | the program name. This allows code using QProcess to be written in a |
502 | cross-platform manner, as shown in the examples above. |
503 | |
504 | QProcess does not support directly executing Unix shell or Windows command |
505 | interpreter built-in functions, such as \c{cmd.exe}'s \c dir command or the |
506 | Bourne shell's \c export. On Unix, even though many shell built-ins are |
507 | also provided as separate executables, their behavior may differ from those |
508 | implemented as built-ins. To run those commands, one should explicitly |
509 | execute the interpreter with suitable options. For Unix systems, launch |
510 | "/bin/sh" with two arguments: "-c" and a string with the command-line to be |
511 | run. For Windows, due to the non-standard way \c{cmd.exe} parses its |
512 | command-line, use setNativeArguments() (for example, "/c dir d:"). |
513 | |
514 | \section1 Environment variables |
515 | |
516 | The QProcess API offers methods to manipulate the environment variables |
517 | that the child process will see. By default, the child process will have a |
518 | copy of the current process environment variables that exist at the time |
519 | the start() function is called. This means that any modifications performed |
520 | using qputenv() prior to that call will be reflected in the child process' |
521 | environment. Note that QProcess makes no attempt to prevent race conditions |
522 | with qputenv() happening in other threads, so it is recommended to avoid |
523 | qputenv() after the application's initial start up. |
524 | |
525 | The environment for a specific child can be modified using the |
526 | processEnvironment() and setProcessEnvironment() functions, which use the |
527 | \l QProcessEnvironment class. By default, processEnvironment() will return |
528 | an object for which QProcessEnvironment::inheritsFromParent() is true. |
529 | Setting an environment that does not inherit from the parent will cause |
530 | QProcess to use exactly that environment for the child when it is started. |
531 | |
532 | The normal scenario starts from the current environment by calling |
533 | QProcessEnvironment::systemEnvironment() and then proceeds to adding, |
534 | changing, or removing specific variables. The resulting variable roster can |
535 | then be applied to a QProcess with setProcessEnvironment(). |
536 | |
537 | It is possible to remove all variables from the environment or to start |
538 | from an empty environment, using the QProcessEnvironment() default |
539 | constructor. This is not advisable outside of controlled and |
540 | system-specific conditions, as there may be system variables that are set |
541 | in the current process environment and are required for proper execution |
542 | of the child process. |
543 | |
544 | On Windows, QProcess will copy the current process' \c "PATH" and \c |
545 | "SystemRoot" environment variables if they were unset. It is not possible |
546 | to unset them completely, but it is possible to set them to empty values. |
547 | Setting \c "PATH" to empty on Windows will likely cause the child process |
548 | to fail to start. |
549 | |
550 | \section1 Communicating via Channels |
551 | |
552 | Processes have two predefined output channels: The standard |
553 | output channel (\c stdout) supplies regular console output, and |
554 | the standard error channel (\c stderr) usually supplies the |
555 | errors that are printed by the process. These channels represent |
556 | two separate streams of data. You can toggle between them by |
557 | calling setReadChannel(). QProcess emits readyRead() when data is |
558 | available on the current read channel. It also emits |
559 | readyReadStandardOutput() when new standard output data is |
560 | available, and when new standard error data is available, |
561 | readyReadStandardError() is emitted. Instead of calling read(), |
562 | readLine(), or getChar(), you can explicitly read all data from |
563 | either of the two channels by calling readAllStandardOutput() or |
564 | readAllStandardError(). |
565 | |
566 | The terminology for the channels can be misleading. Be aware that |
567 | the process's output channels correspond to QProcess's |
568 | \e read channels, whereas the process's input channels correspond |
569 | to QProcess's \e write channels. This is because what we read |
570 | using QProcess is the process's output, and what we write becomes |
571 | the process's input. |
572 | |
573 | QProcess can merge the two output channels, so that standard |
574 | output and standard error data from the running process both use |
575 | the standard output channel. Call setProcessChannelMode() with |
576 | MergedChannels before starting the process to activate |
577 | this feature. You also have the option of forwarding the output of |
578 | the running process to the calling, main process, by passing |
579 | ForwardedChannels as the argument. It is also possible to forward |
580 | only one of the output channels - typically one would use |
581 | ForwardedErrorChannel, but ForwardedOutputChannel also exists. |
582 | Note that using channel forwarding is typically a bad idea in GUI |
583 | applications - you should present errors graphically instead. |
584 | |
585 | Certain processes need special environment settings in order to |
586 | operate. You can set environment variables for your process by |
587 | calling setProcessEnvironment(). To set a working directory, call |
588 | setWorkingDirectory(). By default, processes are run in the |
589 | current working directory of the calling process. |
590 | |
591 | The positioning and the screen Z-order of windows belonging to |
592 | GUI applications started with QProcess are controlled by |
593 | the underlying windowing system. For Qt 5 applications, the |
594 | positioning can be specified using the \c{-qwindowgeometry} |
595 | command line option; X11 applications generally accept a |
596 | \c{-geometry} command line option. |
597 | |
598 | \section1 Synchronous Process API |
599 | |
600 | QProcess provides a set of functions which allow it to be used |
601 | without an event loop, by suspending the calling thread until |
602 | certain signals are emitted: |
603 | |
604 | \list |
605 | \li waitForStarted() blocks until the process has started. |
606 | |
607 | \li waitForReadyRead() blocks until new data is |
608 | available for reading on the current read channel. |
609 | |
610 | \li waitForBytesWritten() blocks until one payload of |
611 | data has been written to the process. |
612 | |
613 | \li waitForFinished() blocks until the process has finished. |
614 | \endlist |
615 | |
616 | Calling these functions from the main thread (the thread that |
617 | calls QApplication::exec()) may cause your user interface to |
618 | freeze. |
619 | |
620 | The following example runs \c gzip to compress the string "Qt |
621 | rocks!", without an event loop: |
622 | |
623 | \snippet process/process.cpp 0 |
624 | |
625 | \sa QBuffer, QFile, QTcpSocket |
626 | */ |
627 | |
628 | /*! |
629 | \enum QProcess::ProcessChannel |
630 | |
631 | This enum describes the process channels used by the running process. |
632 | Pass one of these values to setReadChannel() to set the |
633 | current read channel of QProcess. |
634 | |
635 | \value StandardOutput The standard output (stdout) of the running |
636 | process. |
637 | |
638 | \value StandardError The standard error (stderr) of the running |
639 | process. |
640 | |
641 | \sa setReadChannel() |
642 | */ |
643 | |
644 | /*! |
645 | \enum QProcess::ProcessChannelMode |
646 | |
647 | This enum describes the process output channel modes of QProcess. |
648 | Pass one of these values to setProcessChannelMode() to set the |
649 | current read channel mode. |
650 | |
651 | \value SeparateChannels QProcess manages the output of the |
652 | running process, keeping standard output and standard error data |
653 | in separate internal buffers. You can select the QProcess's |
654 | current read channel by calling setReadChannel(). This is the |
655 | default channel mode of QProcess. |
656 | |
657 | \value MergedChannels QProcess merges the output of the running |
658 | process into the standard output channel (\c stdout). The |
659 | standard error channel (\c stderr) will not receive any data. The |
660 | standard output and standard error data of the running process |
661 | are interleaved. For detached processes, the merged output of the |
662 | running process is forwarded onto the main process. |
663 | |
664 | \value ForwardedChannels QProcess forwards the output of the |
665 | running process onto the main process. Anything the child process |
666 | writes to its standard output and standard error will be written |
667 | to the standard output and standard error of the main process. |
668 | |
669 | \value ForwardedErrorChannel QProcess manages the standard output |
670 | of the running process, but forwards its standard error onto the |
671 | main process. This reflects the typical use of command line tools |
672 | as filters, where the standard output is redirected to another |
673 | process or a file, while standard error is printed to the console |
674 | for diagnostic purposes. |
675 | (This value was introduced in Qt 5.2.) |
676 | |
677 | \value ForwardedOutputChannel Complementary to ForwardedErrorChannel. |
678 | (This value was introduced in Qt 5.2.) |
679 | |
680 | \note Windows intentionally suppresses output from GUI-only |
681 | applications to inherited consoles. |
682 | This does \e not apply to output redirected to files or pipes. |
683 | To forward the output of GUI-only applications on the console |
684 | nonetheless, you must use SeparateChannels and do the forwarding |
685 | yourself by reading the output and writing it to the appropriate |
686 | output channels. |
687 | |
688 | \sa setProcessChannelMode() |
689 | */ |
690 | |
691 | /*! |
692 | \enum QProcess::InputChannelMode |
693 | \since 5.2 |
694 | |
695 | This enum describes the process input channel modes of QProcess. |
696 | Pass one of these values to setInputChannelMode() to set the |
697 | current write channel mode. |
698 | |
699 | \value ManagedInputChannel QProcess manages the input of the running |
700 | process. This is the default input channel mode of QProcess. |
701 | |
702 | \value ForwardedInputChannel QProcess forwards the input of the main |
703 | process onto the running process. The child process reads its standard |
704 | input from the same source as the main process. |
705 | Note that the main process must not try to read its standard input |
706 | while the child process is running. |
707 | |
708 | \sa setInputChannelMode() |
709 | */ |
710 | |
711 | /*! |
712 | \enum QProcess::ProcessError |
713 | |
714 | This enum describes the different types of errors that are |
715 | reported by QProcess. |
716 | |
717 | \value FailedToStart The process failed to start. Either the |
718 | invoked program is missing, or you may have insufficient |
719 | permissions or resources to invoke the program. |
720 | |
721 | \value Crashed The process crashed some time after starting |
722 | successfully. |
723 | |
724 | \value Timedout The last waitFor...() function timed out. The |
725 | state of QProcess is unchanged, and you can try calling |
726 | waitFor...() again. |
727 | |
728 | \value WriteError An error occurred when attempting to write to the |
729 | process. For example, the process may not be running, or it may |
730 | have closed its input channel. |
731 | |
732 | \value ReadError An error occurred when attempting to read from |
733 | the process. For example, the process may not be running. |
734 | |
735 | \value UnknownError An unknown error occurred. This is the default |
736 | return value of error(). |
737 | |
738 | \sa error() |
739 | */ |
740 | |
741 | /*! |
742 | \enum QProcess::ProcessState |
743 | |
744 | This enum describes the different states of QProcess. |
745 | |
746 | \value NotRunning The process is not running. |
747 | |
748 | \value Starting The process is starting, but the program has not |
749 | yet been invoked. |
750 | |
751 | \value Running The process is running and is ready for reading and |
752 | writing. |
753 | |
754 | \sa state() |
755 | */ |
756 | |
757 | /*! |
758 | \enum QProcess::ExitStatus |
759 | |
760 | This enum describes the different exit statuses of QProcess. |
761 | |
762 | \value NormalExit The process exited normally. |
763 | |
764 | \value CrashExit The process crashed. |
765 | |
766 | \sa exitStatus() |
767 | */ |
768 | |
769 | /*! |
770 | \typedef QProcess::CreateProcessArgumentModifier |
771 | \note This typedef is only available on desktop Windows. |
772 | |
773 | On Windows, QProcess uses the Win32 API function \c CreateProcess to |
774 | start child processes. While QProcess provides a comfortable way to start |
775 | processes without worrying about platform |
776 | details, it is in some cases desirable to fine-tune the parameters that are |
777 | passed to \c CreateProcess. This is done by defining a |
778 | \c CreateProcessArgumentModifier function and passing it to |
779 | \c setCreateProcessArgumentsModifier. |
780 | |
781 | A \c CreateProcessArgumentModifier function takes one parameter: a pointer |
782 | to a \c CreateProcessArguments struct. The members of this struct will be |
783 | passed to \c CreateProcess after the \c CreateProcessArgumentModifier |
784 | function is called. |
785 | |
786 | The following example demonstrates how to pass custom flags to |
787 | \c CreateProcess. |
788 | When starting a console process B from a console process A, QProcess will |
789 | reuse the console window of process A for process B by default. In this |
790 | example, a new console window with a custom color scheme is created for the |
791 | child process B instead. |
792 | |
793 | \snippet qprocess/qprocess-createprocessargumentsmodifier.cpp 0 |
794 | |
795 | \sa QProcess::CreateProcessArguments |
796 | \sa setCreateProcessArgumentsModifier() |
797 | */ |
798 | |
799 | /*! |
800 | \class QProcess::CreateProcessArguments |
801 | \inmodule QtCore |
802 | \note This struct is only available on the Windows platform. |
803 | |
804 | This struct is a representation of all parameters of the Windows API |
805 | function \c CreateProcess. It is used as parameter for |
806 | \c CreateProcessArgumentModifier functions. |
807 | |
808 | \sa QProcess::CreateProcessArgumentModifier |
809 | */ |
810 | |
811 | /*! |
812 | \class QProcess::UnixProcessParameters |
813 | \inmodule QtCore |
814 | \note This struct is only available on Unix platforms |
815 | \since 6.6 |
816 | |
817 | This struct can be used to pass extra, Unix-specific configuration for the |
818 | child process using QProcess::setUnixProcessParameters(). |
819 | |
820 | Its members are: |
821 | \list |
822 | \li UnixProcessParameters::flags Flags, see QProcess::UnixProcessFlags |
823 | \li UnixProcessParameters::lowestFileDescriptorToClose The lowest file |
824 | descriptor to close. |
825 | \endlist |
826 | |
827 | When the QProcess::UnixProcessFlags::CloseFileDescriptors flag is set in |
828 | the \c flags field, QProcess closes the application's open file descriptors |
829 | before executing the child process. The descriptors 0, 1, and 2 (that is, |
830 | \c stdin, \c stdout, and \c stderr) are left alone, along with the ones |
831 | numbered lower than the value of the \c lowestFileDescriptorToClose field. |
832 | |
833 | All of the settings above can also be manually achieved by calling the |
834 | respective POSIX function from a handler set with |
835 | QProcess::setChildProcessModifier(). This structure allows QProcess to deal |
836 | with any platform-specific differences, benefit from certain optimizations, |
837 | and reduces code duplication. Moreover, if any of those functions fail, |
838 | QProcess will enter QProcess::FailedToStart state, while the child process |
839 | modifier callback is not allowed to fail. |
840 | |
841 | \sa QProcess::setUnixProcessParameters(), QProcess::setChildProcessModifier() |
842 | */ |
843 | |
844 | /*! |
845 | \enum QProcess::UnixProcessFlag |
846 | \since 6.6 |
847 | |
848 | These flags can be used in the \c flags field of \l UnixProcessParameters. |
849 | |
850 | \value CloseFileDescriptors Close all file descriptors above the threshold |
851 | defined by \c lowestFileDescriptorToClose, preventing any currently |
852 | open descriptor in the parent process from accidentally leaking to the |
853 | child. The \c stdin, \c stdout, and \c stderr file descriptors are |
854 | never closed. |
855 | |
856 | \value [since 6.7] CreateNewSession Starts a new process session, by calling |
857 | \c{setsid(2)}. This allows the child process to outlive the session |
858 | the current process is in. This is one of the steps that |
859 | startDetached() takes to allow the process to detach, and is also one |
860 | of the steps to daemonize a process. |
861 | |
862 | \value [since 6.7] DisconnectControllingTerminal Requests that the process |
863 | disconnect from its controlling terminal, if it has one. If it has |
864 | none, nothing happens. Processes still connected to a controlling |
865 | terminal may get a Hang Up (\c SIGHUP) signal if the terminal |
866 | closes, or one of the other terminal-control signals (\c SIGTSTP, \c |
867 | SIGTTIN, \c SIGTTOU). Note that on some operating systems, a process |
868 | may only disconnect from the controlling terminal if it is the |
869 | session leader, meaning the \c CreateNewSession flag may be |
870 | required. Like it, this is one of the steps to daemonize a process. |
871 | |
872 | \value IgnoreSigPipe Always sets the \c SIGPIPE signal to ignored |
873 | (\c SIG_IGN), even if the \c ResetSignalHandlers flag was set. By |
874 | default, if the child attempts to write to its standard output or |
875 | standard error after the respective channel was closed with |
876 | QProcess::closeReadChannel(), it would get the \c SIGPIPE signal and |
877 | terminate immediately; with this flag, the write operation fails |
878 | without a signal and the child may continue executing. |
879 | |
880 | \value [since 6.7] ResetIds Drops any retained, effective user or group |
881 | ID the current process may still have (see \c{setuid(2)} and |
882 | \c{setgid(2)}, plus QCoreApplication::setSetuidAllowed()). This is |
883 | useful if the current process was setuid or setgid and does not wish |
884 | the child process to retain the elevated privileges. |
885 | |
886 | \value ResetSignalHandlers Resets all Unix signal handlers back to their |
887 | default state (that is, pass \c SIG_DFL to \c{signal(2)}). This flag |
888 | is useful to ensure any ignored (\c SIG_IGN) signal does not affect |
889 | the child's behavior. |
890 | |
891 | \value UseVFork Requests that QProcess use \c{vfork(2)} to start the child |
892 | process. Use this flag to indicate that the callback function set |
893 | with setChildProcessModifier() is safe to execute in the child side of |
894 | a \c{vfork(2)}; that is, the callback does not modify any non-local |
895 | variables (directly or through any function it calls), nor attempts |
896 | to communicate with the parent process. It is implementation-defined |
897 | if QProcess will actually use \c{vfork(2)} and if \c{vfork(2)} is |
898 | different from standard \c{fork(2)}. |
899 | |
900 | \sa setUnixProcessParameters(), unixProcessParameters() |
901 | */ |
902 | |
903 | /*! |
904 | \fn void QProcess::errorOccurred(QProcess::ProcessError error) |
905 | \since 5.6 |
906 | |
907 | This signal is emitted when an error occurs with the process. The |
908 | specified \a error describes the type of error that occurred. |
909 | */ |
910 | |
911 | /*! |
912 | \fn void QProcess::started() |
913 | |
914 | This signal is emitted by QProcess when the process has started, |
915 | and state() returns \l Running. |
916 | */ |
917 | |
918 | /*! |
919 | \fn void QProcess::stateChanged(QProcess::ProcessState newState) |
920 | |
921 | This signal is emitted whenever the state of QProcess changes. The |
922 | \a newState argument is the state QProcess changed to. |
923 | */ |
924 | |
925 | /*! |
926 | \fn void QProcess::finished(int exitCode, QProcess::ExitStatus exitStatus) |
927 | |
928 | This signal is emitted when the process finishes. \a exitCode is the exit |
929 | code of the process (only valid for normal exits), and \a exitStatus is |
930 | the exit status. |
931 | After the process has finished, the buffers in QProcess are still intact. |
932 | You can still read any data that the process may have written before it |
933 | finished. |
934 | |
935 | \sa exitStatus() |
936 | */ |
937 | |
938 | /*! |
939 | \fn void QProcess::readyReadStandardOutput() |
940 | |
941 | This signal is emitted when the process has made new data |
942 | available through its standard output channel (\c stdout). It is |
943 | emitted regardless of the current \l{readChannel()}{read channel}. |
944 | |
945 | \sa readAllStandardOutput(), readChannel() |
946 | */ |
947 | |
948 | /*! |
949 | \fn void QProcess::readyReadStandardError() |
950 | |
951 | This signal is emitted when the process has made new data |
952 | available through its standard error channel (\c stderr). It is |
953 | emitted regardless of the current \l{readChannel()}{read |
954 | channel}. |
955 | |
956 | \sa readAllStandardError(), readChannel() |
957 | */ |
958 | |
959 | /*! |
960 | \internal |
961 | */ |
962 | QProcessPrivate::QProcessPrivate() |
963 | { |
964 | readBufferChunkSize = QRINGBUFFER_CHUNKSIZE; |
965 | #ifndef Q_OS_WIN |
966 | writeBufferChunkSize = QRINGBUFFER_CHUNKSIZE; |
967 | #endif |
968 | } |
969 | |
970 | /*! |
971 | \internal |
972 | */ |
973 | QProcessPrivate::~QProcessPrivate() |
974 | { |
975 | if (stdinChannel.process) |
976 | stdinChannel.process->stdoutChannel.clear(); |
977 | if (stdoutChannel.process) |
978 | stdoutChannel.process->stdinChannel.clear(); |
979 | } |
980 | |
981 | /*! |
982 | \internal |
983 | */ |
984 | void QProcessPrivate::setError(QProcess::ProcessError error, const QString &description) |
985 | { |
986 | processError = error; |
987 | if (description.isEmpty()) { |
988 | switch (error) { |
989 | case QProcess::FailedToStart: |
990 | errorString = QProcess::tr(s: "Process failed to start" ); |
991 | break; |
992 | case QProcess::Crashed: |
993 | errorString = QProcess::tr(s: "Process crashed" ); |
994 | break; |
995 | case QProcess::Timedout: |
996 | errorString = QProcess::tr(s: "Process operation timed out" ); |
997 | break; |
998 | case QProcess::ReadError: |
999 | errorString = QProcess::tr(s: "Error reading from process" ); |
1000 | break; |
1001 | case QProcess::WriteError: |
1002 | errorString = QProcess::tr(s: "Error writing to process" ); |
1003 | break; |
1004 | case QProcess::UnknownError: |
1005 | errorString.clear(); |
1006 | break; |
1007 | } |
1008 | } else { |
1009 | errorString = description; |
1010 | } |
1011 | } |
1012 | |
1013 | /*! |
1014 | \internal |
1015 | */ |
1016 | void QProcessPrivate::setErrorAndEmit(QProcess::ProcessError error, const QString &description) |
1017 | { |
1018 | Q_Q(QProcess); |
1019 | Q_ASSERT(error != QProcess::UnknownError); |
1020 | setError(error, description); |
1021 | emit q->errorOccurred(error: QProcess::ProcessError(processError)); |
1022 | } |
1023 | |
1024 | /*! |
1025 | \internal |
1026 | */ |
1027 | bool QProcessPrivate::openChannels() |
1028 | { |
1029 | // stdin channel. |
1030 | if (inputChannelMode == QProcess::ForwardedInputChannel) { |
1031 | if (stdinChannel.type != Channel::Normal) |
1032 | qWarning(msg: "QProcess::openChannels: Inconsistent stdin channel configuration" ); |
1033 | } else if (!openChannel(channel&: stdinChannel)) { |
1034 | return false; |
1035 | } |
1036 | |
1037 | // stdout channel. |
1038 | if (processChannelMode == QProcess::ForwardedChannels |
1039 | || processChannelMode == QProcess::ForwardedOutputChannel) { |
1040 | if (stdoutChannel.type != Channel::Normal) |
1041 | qWarning(msg: "QProcess::openChannels: Inconsistent stdout channel configuration" ); |
1042 | } else if (!openChannel(channel&: stdoutChannel)) { |
1043 | return false; |
1044 | } |
1045 | |
1046 | // stderr channel. |
1047 | if (processChannelMode == QProcess::ForwardedChannels |
1048 | || processChannelMode == QProcess::ForwardedErrorChannel |
1049 | || processChannelMode == QProcess::MergedChannels) { |
1050 | if (stderrChannel.type != Channel::Normal) |
1051 | qWarning(msg: "QProcess::openChannels: Inconsistent stderr channel configuration" ); |
1052 | } else if (!openChannel(channel&: stderrChannel)) { |
1053 | return false; |
1054 | } |
1055 | |
1056 | return true; |
1057 | } |
1058 | |
1059 | /*! |
1060 | \internal |
1061 | */ |
1062 | void QProcessPrivate::closeChannels() |
1063 | { |
1064 | closeChannel(channel: &stdoutChannel); |
1065 | closeChannel(channel: &stderrChannel); |
1066 | closeChannel(channel: &stdinChannel); |
1067 | } |
1068 | |
1069 | /*! |
1070 | \internal |
1071 | */ |
1072 | bool QProcessPrivate::openChannelsForDetached() |
1073 | { |
1074 | // stdin channel. |
1075 | bool needToOpen = (stdinChannel.type == Channel::Redirect |
1076 | || stdinChannel.type == Channel::PipeSink); |
1077 | if (stdinChannel.type != Channel::Normal |
1078 | && (!needToOpen |
1079 | || inputChannelMode == QProcess::ForwardedInputChannel)) { |
1080 | qWarning(msg: "QProcess::openChannelsForDetached: Inconsistent stdin channel configuration" ); |
1081 | } |
1082 | if (needToOpen && !openChannel(channel&: stdinChannel)) |
1083 | return false; |
1084 | |
1085 | // stdout channel. |
1086 | needToOpen = (stdoutChannel.type == Channel::Redirect |
1087 | || stdoutChannel.type == Channel::PipeSource); |
1088 | if (stdoutChannel.type != Channel::Normal |
1089 | && (!needToOpen |
1090 | || processChannelMode == QProcess::ForwardedChannels |
1091 | || processChannelMode == QProcess::ForwardedOutputChannel)) { |
1092 | qWarning(msg: "QProcess::openChannelsForDetached: Inconsistent stdout channel configuration" ); |
1093 | } |
1094 | if (needToOpen && !openChannel(channel&: stdoutChannel)) |
1095 | return false; |
1096 | |
1097 | // stderr channel. |
1098 | needToOpen = (stderrChannel.type == Channel::Redirect); |
1099 | if (stderrChannel.type != Channel::Normal |
1100 | && (!needToOpen |
1101 | || processChannelMode == QProcess::ForwardedChannels |
1102 | || processChannelMode == QProcess::ForwardedErrorChannel |
1103 | || processChannelMode == QProcess::MergedChannels)) { |
1104 | qWarning(msg: "QProcess::openChannelsForDetached: Inconsistent stderr channel configuration" ); |
1105 | } |
1106 | if (needToOpen && !openChannel(channel&: stderrChannel)) |
1107 | return false; |
1108 | |
1109 | return true; |
1110 | } |
1111 | |
1112 | /*! |
1113 | \internal |
1114 | Returns \c true if we emitted readyRead(). |
1115 | */ |
1116 | bool QProcessPrivate::tryReadFromChannel(Channel *channel) |
1117 | { |
1118 | Q_Q(QProcess); |
1119 | if (channel->pipe[0] == INVALID_Q_PIPE) |
1120 | return false; |
1121 | |
1122 | qint64 available = bytesAvailableInChannel(channel); |
1123 | if (available == 0) |
1124 | available = 1; // always try to read at least one byte |
1125 | |
1126 | QProcess::ProcessChannel channelIdx = (channel == &stdoutChannel |
1127 | ? QProcess::StandardOutput |
1128 | : QProcess::StandardError); |
1129 | Q_ASSERT(readBuffers.size() > int(channelIdx)); |
1130 | QRingBuffer &readBuffer = readBuffers[int(channelIdx)]; |
1131 | char *ptr = readBuffer.reserve(bytes: available); |
1132 | qint64 readBytes = readFromChannel(channel, data: ptr, maxlen: available); |
1133 | if (readBytes <= 0) |
1134 | readBuffer.chop(bytes: available); |
1135 | if (readBytes == -2) { |
1136 | // EWOULDBLOCK |
1137 | return false; |
1138 | } |
1139 | if (readBytes == -1) { |
1140 | setErrorAndEmit(error: QProcess::ReadError); |
1141 | #if defined QPROCESS_DEBUG |
1142 | qDebug("QProcessPrivate::tryReadFromChannel(%d), failed to read from the process" , |
1143 | int(channel - &stdinChannel)); |
1144 | #endif |
1145 | return false; |
1146 | } |
1147 | if (readBytes == 0) { |
1148 | // EOF |
1149 | closeChannel(channel); |
1150 | #if defined QPROCESS_DEBUG |
1151 | qDebug("QProcessPrivate::tryReadFromChannel(%d), 0 bytes available" , |
1152 | int(channel - &stdinChannel)); |
1153 | #endif |
1154 | return false; |
1155 | } |
1156 | #if defined QPROCESS_DEBUG |
1157 | qDebug("QProcessPrivate::tryReadFromChannel(%d), read %lld bytes from the process' output" , |
1158 | int(channel - &stdinChannel), readBytes); |
1159 | #endif |
1160 | |
1161 | if (channel->closed) { |
1162 | readBuffer.chop(bytes: readBytes); |
1163 | return false; |
1164 | } |
1165 | |
1166 | readBuffer.chop(bytes: available - readBytes); |
1167 | |
1168 | bool didRead = false; |
1169 | if (currentReadChannel == channelIdx) { |
1170 | didRead = true; |
1171 | if (!emittedReadyRead) { |
1172 | QScopedValueRollback<bool> guard(emittedReadyRead, true); |
1173 | emit q->readyRead(); |
1174 | } |
1175 | } |
1176 | emit q->channelReadyRead(channel: int(channelIdx)); |
1177 | if (channelIdx == QProcess::StandardOutput) |
1178 | emit q->readyReadStandardOutput(QProcess::QPrivateSignal()); |
1179 | else |
1180 | emit q->readyReadStandardError(QProcess::QPrivateSignal()); |
1181 | return didRead; |
1182 | } |
1183 | |
1184 | /*! |
1185 | \internal |
1186 | */ |
1187 | bool QProcessPrivate::_q_canReadStandardOutput() |
1188 | { |
1189 | return tryReadFromChannel(channel: &stdoutChannel); |
1190 | } |
1191 | |
1192 | /*! |
1193 | \internal |
1194 | */ |
1195 | bool QProcessPrivate::_q_canReadStandardError() |
1196 | { |
1197 | return tryReadFromChannel(channel: &stderrChannel); |
1198 | } |
1199 | |
1200 | /*! |
1201 | \internal |
1202 | */ |
1203 | void QProcessPrivate::_q_processDied() |
1204 | { |
1205 | #if defined QPROCESS_DEBUG |
1206 | qDebug("QProcessPrivate::_q_processDied()" ); |
1207 | #endif |
1208 | |
1209 | // in case there is data in the pipeline and this slot by chance |
1210 | // got called before the read notifications, call these functions |
1211 | // so the data is made available before we announce death. |
1212 | #ifdef Q_OS_WIN |
1213 | drainOutputPipes(); |
1214 | #else |
1215 | _q_canReadStandardOutput(); |
1216 | _q_canReadStandardError(); |
1217 | #endif |
1218 | |
1219 | // Slots connected to signals emitted by the functions called above |
1220 | // might call waitFor*(), which would synchronously reap the process. |
1221 | // So check the state to avoid trying to reap a second time. |
1222 | if (processState != QProcess::NotRunning) |
1223 | processFinished(); |
1224 | } |
1225 | |
1226 | /*! |
1227 | \internal |
1228 | */ |
1229 | void QProcessPrivate::processFinished() |
1230 | { |
1231 | Q_Q(QProcess); |
1232 | #if defined QPROCESS_DEBUG |
1233 | qDebug("QProcessPrivate::processFinished()" ); |
1234 | #endif |
1235 | |
1236 | #ifdef Q_OS_UNIX |
1237 | waitForDeadChild(); |
1238 | #else |
1239 | findExitCode(); |
1240 | #endif |
1241 | |
1242 | cleanup(); |
1243 | |
1244 | if (exitStatus == QProcess::CrashExit) |
1245 | setErrorAndEmit(error: QProcess::Crashed); |
1246 | |
1247 | // we received EOF now: |
1248 | emit q->readChannelFinished(); |
1249 | // in the future: |
1250 | //emit q->standardOutputClosed(); |
1251 | //emit q->standardErrorClosed(); |
1252 | |
1253 | emit q->finished(exitCode, exitStatus: QProcess::ExitStatus(exitStatus)); |
1254 | |
1255 | #if defined QPROCESS_DEBUG |
1256 | qDebug("QProcessPrivate::processFinished(): process is dead" ); |
1257 | #endif |
1258 | } |
1259 | |
1260 | /*! |
1261 | \internal |
1262 | */ |
1263 | bool QProcessPrivate::_q_startupNotification() |
1264 | { |
1265 | Q_Q(QProcess); |
1266 | #if defined QPROCESS_DEBUG |
1267 | qDebug("QProcessPrivate::startupNotification()" ); |
1268 | #endif |
1269 | |
1270 | QString errorMessage; |
1271 | if (processStarted(errorMessage: &errorMessage)) { |
1272 | q->setProcessState(QProcess::Running); |
1273 | emit q->started(QProcess::QPrivateSignal()); |
1274 | return true; |
1275 | } |
1276 | |
1277 | q->setProcessState(QProcess::NotRunning); |
1278 | setErrorAndEmit(error: QProcess::FailedToStart, description: errorMessage); |
1279 | #ifdef Q_OS_UNIX |
1280 | waitForDeadChild(); |
1281 | #endif |
1282 | cleanup(); |
1283 | return false; |
1284 | } |
1285 | |
1286 | /*! |
1287 | \internal |
1288 | */ |
1289 | void QProcessPrivate::closeWriteChannel() |
1290 | { |
1291 | #if defined QPROCESS_DEBUG |
1292 | qDebug("QProcessPrivate::closeWriteChannel()" ); |
1293 | #endif |
1294 | |
1295 | closeChannel(channel: &stdinChannel); |
1296 | } |
1297 | |
1298 | /*! |
1299 | Constructs a QProcess object with the given \a parent. |
1300 | */ |
1301 | QProcess::QProcess(QObject *parent) |
1302 | : QIODevice(*new QProcessPrivate, parent) |
1303 | { |
1304 | #if defined QPROCESS_DEBUG |
1305 | qDebug("QProcess::QProcess(%p)" , parent); |
1306 | #endif |
1307 | } |
1308 | |
1309 | /*! |
1310 | Destructs the QProcess object, i.e., killing the process. |
1311 | |
1312 | Note that this function will not return until the process is |
1313 | terminated. |
1314 | */ |
1315 | QProcess::~QProcess() |
1316 | { |
1317 | Q_D(QProcess); |
1318 | if (d->processState != NotRunning) { |
1319 | qWarning().nospace() |
1320 | << "QProcess: Destroyed while process (" << QDir::toNativeSeparators(pathName: program()) << ") is still running." ; |
1321 | kill(); |
1322 | waitForFinished(); |
1323 | } |
1324 | d->cleanup(); |
1325 | } |
1326 | |
1327 | /*! |
1328 | \since 4.2 |
1329 | |
1330 | Returns the channel mode of the QProcess standard output and |
1331 | standard error channels. |
1332 | |
1333 | \sa setProcessChannelMode(), ProcessChannelMode, setReadChannel() |
1334 | */ |
1335 | QProcess::ProcessChannelMode QProcess::processChannelMode() const |
1336 | { |
1337 | Q_D(const QProcess); |
1338 | return ProcessChannelMode(d->processChannelMode); |
1339 | } |
1340 | |
1341 | /*! |
1342 | \since 4.2 |
1343 | |
1344 | Sets the channel mode of the QProcess standard output and standard |
1345 | error channels to the \a mode specified. |
1346 | This mode will be used the next time start() is called. For example: |
1347 | |
1348 | \snippet code/src_corelib_io_qprocess.cpp 0 |
1349 | |
1350 | \sa processChannelMode(), ProcessChannelMode, setReadChannel() |
1351 | */ |
1352 | void QProcess::setProcessChannelMode(ProcessChannelMode mode) |
1353 | { |
1354 | Q_D(QProcess); |
1355 | d->processChannelMode = mode; |
1356 | } |
1357 | |
1358 | /*! |
1359 | \since 5.2 |
1360 | |
1361 | Returns the channel mode of the QProcess standard input channel. |
1362 | |
1363 | \sa setInputChannelMode(), InputChannelMode |
1364 | */ |
1365 | QProcess::InputChannelMode QProcess::inputChannelMode() const |
1366 | { |
1367 | Q_D(const QProcess); |
1368 | return InputChannelMode(d->inputChannelMode); |
1369 | } |
1370 | |
1371 | /*! |
1372 | \since 5.2 |
1373 | |
1374 | Sets the channel mode of the QProcess standard input |
1375 | channel to the \a mode specified. |
1376 | This mode will be used the next time start() is called. |
1377 | |
1378 | \sa inputChannelMode(), InputChannelMode |
1379 | */ |
1380 | void QProcess::setInputChannelMode(InputChannelMode mode) |
1381 | { |
1382 | Q_D(QProcess); |
1383 | d->inputChannelMode = mode; |
1384 | } |
1385 | |
1386 | /*! |
1387 | Returns the current read channel of the QProcess. |
1388 | |
1389 | \sa setReadChannel() |
1390 | */ |
1391 | QProcess::ProcessChannel QProcess::readChannel() const |
1392 | { |
1393 | Q_D(const QProcess); |
1394 | return ProcessChannel(d->currentReadChannel); |
1395 | } |
1396 | |
1397 | /*! |
1398 | Sets the current read channel of the QProcess to the given \a |
1399 | channel. The current input channel is used by the functions |
1400 | read(), readAll(), readLine(), and getChar(). It also determines |
1401 | which channel triggers QProcess to emit readyRead(). |
1402 | |
1403 | \sa readChannel() |
1404 | */ |
1405 | void QProcess::setReadChannel(ProcessChannel channel) |
1406 | { |
1407 | QIODevice::setCurrentReadChannel(int(channel)); |
1408 | } |
1409 | |
1410 | /*! |
1411 | Closes the read channel \a channel. After calling this function, |
1412 | QProcess will no longer receive data on the channel. Any data that |
1413 | has already been received is still available for reading. |
1414 | |
1415 | Call this function to save memory, if you are not interested in |
1416 | the output of the process. |
1417 | |
1418 | \sa closeWriteChannel(), setReadChannel() |
1419 | */ |
1420 | void QProcess::closeReadChannel(ProcessChannel channel) |
1421 | { |
1422 | Q_D(QProcess); |
1423 | |
1424 | if (channel == StandardOutput) |
1425 | d->stdoutChannel.closed = true; |
1426 | else |
1427 | d->stderrChannel.closed = true; |
1428 | } |
1429 | |
1430 | /*! |
1431 | Schedules the write channel of QProcess to be closed. The channel |
1432 | will close once all data has been written to the process. After |
1433 | calling this function, any attempts to write to the process will |
1434 | fail. |
1435 | |
1436 | Closing the write channel is necessary for programs that read |
1437 | input data until the channel has been closed. For example, the |
1438 | program "more" is used to display text data in a console on both |
1439 | Unix and Windows. But it will not display the text data until |
1440 | QProcess's write channel has been closed. Example: |
1441 | |
1442 | \snippet code/src_corelib_io_qprocess.cpp 1 |
1443 | |
1444 | The write channel is implicitly opened when start() is called. |
1445 | |
1446 | \sa closeReadChannel() |
1447 | */ |
1448 | void QProcess::closeWriteChannel() |
1449 | { |
1450 | Q_D(QProcess); |
1451 | d->stdinChannel.closed = true; // closing |
1452 | if (bytesToWrite() == 0) |
1453 | d->closeWriteChannel(); |
1454 | } |
1455 | |
1456 | /*! |
1457 | \since 4.2 |
1458 | |
1459 | Redirects the process' standard input to the file indicated by \a |
1460 | fileName. When an input redirection is in place, the QProcess |
1461 | object will be in read-only mode (calling write() will result in |
1462 | error). |
1463 | |
1464 | To make the process read EOF right away, pass nullDevice() here. |
1465 | This is cleaner than using closeWriteChannel() before writing any |
1466 | data, because it can be set up prior to starting the process. |
1467 | |
1468 | If the file \a fileName does not exist at the moment start() is |
1469 | called or is not readable, starting the process will fail. |
1470 | |
1471 | Calling setStandardInputFile() after the process has started has no |
1472 | effect. |
1473 | |
1474 | \sa setStandardOutputFile(), setStandardErrorFile(), |
1475 | setStandardOutputProcess() |
1476 | */ |
1477 | void QProcess::setStandardInputFile(const QString &fileName) |
1478 | { |
1479 | Q_D(QProcess); |
1480 | d->stdinChannel = fileName; |
1481 | } |
1482 | |
1483 | /*! |
1484 | \since 4.2 |
1485 | |
1486 | Redirects the process' standard output to the file \a |
1487 | fileName. When the redirection is in place, the standard output |
1488 | read channel is closed: reading from it using read() will always |
1489 | fail, as will readAllStandardOutput(). |
1490 | |
1491 | To discard all standard output from the process, pass nullDevice() |
1492 | here. This is more efficient than simply never reading the standard |
1493 | output, as no QProcess buffers are filled. |
1494 | |
1495 | If the file \a fileName doesn't exist at the moment start() is |
1496 | called, it will be created. If it cannot be created, the starting |
1497 | will fail. |
1498 | |
1499 | If the file exists and \a mode is QIODevice::Truncate, the file |
1500 | will be truncated. Otherwise (if \a mode is QIODevice::Append), |
1501 | the file will be appended to. |
1502 | |
1503 | Calling setStandardOutputFile() after the process has started has |
1504 | no effect. |
1505 | |
1506 | If \a fileName is an empty string, it stops redirecting the standard |
1507 | output. This is useful for restoring the standard output after redirection. |
1508 | |
1509 | \sa setStandardInputFile(), setStandardErrorFile(), |
1510 | setStandardOutputProcess() |
1511 | */ |
1512 | void QProcess::setStandardOutputFile(const QString &fileName, OpenMode mode) |
1513 | { |
1514 | Q_ASSERT(mode == Append || mode == Truncate); |
1515 | Q_D(QProcess); |
1516 | |
1517 | d->stdoutChannel = fileName; |
1518 | d->stdoutChannel.append = mode == Append; |
1519 | } |
1520 | |
1521 | /*! |
1522 | \since 4.2 |
1523 | |
1524 | Redirects the process' standard error to the file \a |
1525 | fileName. When the redirection is in place, the standard error |
1526 | read channel is closed: reading from it using read() will always |
1527 | fail, as will readAllStandardError(). The file will be appended to |
1528 | if \a mode is Append, otherwise, it will be truncated. |
1529 | |
1530 | See setStandardOutputFile() for more information on how the file |
1531 | is opened. |
1532 | |
1533 | Note: if setProcessChannelMode() was called with an argument of |
1534 | QProcess::MergedChannels, this function has no effect. |
1535 | |
1536 | \sa setStandardInputFile(), setStandardOutputFile(), |
1537 | setStandardOutputProcess() |
1538 | */ |
1539 | void QProcess::setStandardErrorFile(const QString &fileName, OpenMode mode) |
1540 | { |
1541 | Q_ASSERT(mode == Append || mode == Truncate); |
1542 | Q_D(QProcess); |
1543 | |
1544 | d->stderrChannel = fileName; |
1545 | d->stderrChannel.append = mode == Append; |
1546 | } |
1547 | |
1548 | /*! |
1549 | \since 4.2 |
1550 | |
1551 | Pipes the standard output stream of this process to the \a |
1552 | destination process' standard input. |
1553 | |
1554 | The following shell command: |
1555 | \snippet code/src_corelib_io_qprocess.cpp 2 |
1556 | |
1557 | Can be accomplished with QProcess with the following code: |
1558 | \snippet code/src_corelib_io_qprocess.cpp 3 |
1559 | */ |
1560 | void QProcess::setStandardOutputProcess(QProcess *destination) |
1561 | { |
1562 | QProcessPrivate *dfrom = d_func(); |
1563 | QProcessPrivate *dto = destination->d_func(); |
1564 | dfrom->stdoutChannel.pipeTo(other: dto); |
1565 | dto->stdinChannel.pipeFrom(other: dfrom); |
1566 | } |
1567 | |
1568 | #if defined(Q_OS_WIN) || defined(Q_QDOC) |
1569 | |
1570 | /*! |
1571 | \since 4.7 |
1572 | |
1573 | Returns the additional native command line arguments for the program. |
1574 | |
1575 | \note This function is available only on the Windows platform. |
1576 | |
1577 | \sa setNativeArguments() |
1578 | */ |
1579 | QString QProcess::nativeArguments() const |
1580 | { |
1581 | Q_D(const QProcess); |
1582 | return d->nativeArguments; |
1583 | } |
1584 | |
1585 | /*! |
1586 | \since 4.7 |
1587 | \overload |
1588 | |
1589 | Sets additional native command line \a arguments for the program. |
1590 | |
1591 | On operating systems where the system API for passing command line |
1592 | \a arguments to a subprocess natively uses a single string, one can |
1593 | conceive command lines which cannot be passed via QProcess's portable |
1594 | list-based API. In such cases this function must be used to set a |
1595 | string which is \e appended to the string composed from the usual |
1596 | argument list, with a delimiting space. |
1597 | |
1598 | \note This function is available only on the Windows platform. |
1599 | |
1600 | \sa nativeArguments() |
1601 | */ |
1602 | void QProcess::setNativeArguments(const QString &arguments) |
1603 | { |
1604 | Q_D(QProcess); |
1605 | d->nativeArguments = arguments; |
1606 | } |
1607 | |
1608 | /*! |
1609 | \since 5.7 |
1610 | |
1611 | Returns a previously set \c CreateProcess modifier function. |
1612 | |
1613 | \note This function is available only on the Windows platform. |
1614 | |
1615 | \sa setCreateProcessArgumentsModifier() |
1616 | \sa QProcess::CreateProcessArgumentModifier |
1617 | */ |
1618 | QProcess::CreateProcessArgumentModifier QProcess::createProcessArgumentsModifier() const |
1619 | { |
1620 | Q_D(const QProcess); |
1621 | return d->modifyCreateProcessArgs; |
1622 | } |
1623 | |
1624 | /*! |
1625 | \since 5.7 |
1626 | |
1627 | Sets the \a modifier for the \c CreateProcess Win32 API call. |
1628 | Pass \c QProcess::CreateProcessArgumentModifier() to remove a previously set one. |
1629 | |
1630 | \note This function is available only on the Windows platform and requires |
1631 | C++11. |
1632 | |
1633 | \sa QProcess::CreateProcessArgumentModifier, setChildProcessModifier() |
1634 | */ |
1635 | void QProcess::setCreateProcessArgumentsModifier(CreateProcessArgumentModifier modifier) |
1636 | { |
1637 | Q_D(QProcess); |
1638 | d->modifyCreateProcessArgs = modifier; |
1639 | } |
1640 | |
1641 | #endif |
1642 | |
1643 | #if defined(Q_OS_UNIX) || defined(Q_QDOC) |
1644 | /*! |
1645 | \since 6.0 |
1646 | |
1647 | Returns the modifier function previously set by calling |
1648 | setChildProcessModifier(). |
1649 | |
1650 | \note This function is only available on Unix platforms. |
1651 | |
1652 | \sa setChildProcessModifier(), unixProcessParameters() |
1653 | */ |
1654 | std::function<void(void)> QProcess::childProcessModifier() const |
1655 | { |
1656 | Q_D(const QProcess); |
1657 | return d->unixExtras ? d->unixExtras->childProcessModifier : std::function<void(void)>(); |
1658 | } |
1659 | |
1660 | /*! |
1661 | \since 6.0 |
1662 | |
1663 | Sets the \a modifier function for the child process, for Unix systems |
1664 | (including \macos; for Windows, see setCreateProcessArgumentsModifier()). |
1665 | The function contained by the \a modifier argument will be invoked in the |
1666 | child process after \c{fork()} or \c{vfork()} is completed and QProcess has |
1667 | set up the standard file descriptors for the child process, but before |
1668 | \c{execve()}, inside start(). |
1669 | |
1670 | The following shows an example of setting up a child process to run without |
1671 | privileges: |
1672 | |
1673 | \snippet code/src_corelib_io_qprocess.cpp 4 |
1674 | |
1675 | If the modifier function experiences a failure condition, it can use |
1676 | failChildProcessModifier() to report the situation to the QProcess caller. |
1677 | Alternatively, it may use other methods of stopping the process, like |
1678 | \c{_exit()}, or \c{abort()}. |
1679 | |
1680 | Certain properties of the child process, such as closing all extraneous |
1681 | file descriptors or disconnecting from the controlling TTY, can be more |
1682 | readily achieved by using setUnixProcessParameters(), which can detect |
1683 | failure and report a \l{QProcess::}{FailedToStart} condition. The modifier |
1684 | is useful to change certain uncommon properties of the child process, such |
1685 | as setting up additional file descriptors. If both a child process modifier |
1686 | and Unix process parameters are set, the modifier is run before these |
1687 | parameters are applied. |
1688 | |
1689 | \note In multithreaded applications, this function must be careful not to |
1690 | call any functions that may lock mutexes that may have been in use in |
1691 | other threads (in general, using only functions defined by POSIX as |
1692 | "async-signal-safe" is advised). Most of the Qt API is unsafe inside this |
1693 | callback, including qDebug(), and may lead to deadlocks. |
1694 | |
1695 | \note If the UnixProcessParameters::UseVFork flag is set via |
1696 | setUnixProcessParameters(), QProcess may use \c{vfork()} semantics to |
1697 | start the child process, so this function must obey even stricter |
1698 | constraints. First, because it is still sharing memory with the parent |
1699 | process, it must not write to any non-local variable and must obey proper |
1700 | ordering semantics when reading from them, to avoid data races. Second, |
1701 | even more library functions may misbehave; therefore, this function should |
1702 | only make use of low-level system calls, such as \c{read()}, |
1703 | \c{write()}, \c{setsid()}, \c{nice()}, and similar. |
1704 | |
1705 | \sa childProcessModifier(), failChildProcessModifier(), setUnixProcessParameters() |
1706 | */ |
1707 | void QProcess::setChildProcessModifier(const std::function<void(void)> &modifier) |
1708 | { |
1709 | Q_D(QProcess); |
1710 | if (!d->unixExtras) |
1711 | d->unixExtras.reset(p: new QProcessPrivate::UnixExtras); |
1712 | d->unixExtras->childProcessModifier = modifier; |
1713 | } |
1714 | |
1715 | /*! |
1716 | \fn void QProcess::failChildProcessModifier(const char *description, int error) noexcept |
1717 | \since 6.7 |
1718 | |
1719 | This functions can be used inside the modifier set with |
1720 | setChildProcessModifier() to indicate an error condition was encountered. |
1721 | When the modifier calls these functions, QProcess will emit errorOccurred() |
1722 | with code QProcess::FailedToStart in the parent process. The \a description |
1723 | can be used to include some information in errorString() to help diagnose |
1724 | the problem, usually the name of the call that failed, similar to the C |
1725 | Library function \c{perror()}. Additionally, the \a error parameter can be |
1726 | an \c{<errno.h>} error code whose text form will also be included. |
1727 | |
1728 | For example, a child modifier could prepare an extra file descriptor for |
1729 | the child process this way: |
1730 | |
1731 | \code |
1732 | process.setChildProcessModifier([fd, &process]() { |
1733 | if (dup2(fd, TargetFileDescriptor) < 0) |
1734 | process.failChildProcessModifier(errno, "aux comm channel"); |
1735 | }); |
1736 | process.start(); |
1737 | \endcode |
1738 | |
1739 | Where \c{fd} is a file descriptor currently open in the parent process. If |
1740 | the \c{dup2()} system call resulted in an \c EBADF condition, the process |
1741 | errorString() could be "Child process modifier reported error: aux comm |
1742 | channel: Bad file descriptor". |
1743 | |
1744 | This function does not return to the caller. Using it anywhere except in |
1745 | the child modifier and with the correct QProcess object is undefined |
1746 | behavior. |
1747 | |
1748 | \note The implementation imposes a length limit to the \a description |
1749 | parameter to about 500 characters. This does not include the text from the |
1750 | \a error code. |
1751 | |
1752 | \sa setChildProcessModifier(), setUnixProcessParameters() |
1753 | */ |
1754 | |
1755 | /*! |
1756 | \since 6.6 |
1757 | Returns the \l UnixProcessParameters object describing extra flags and |
1758 | settings that will be applied to the child process on Unix systems. The |
1759 | default settings correspond to a default-constructed UnixProcessParameters. |
1760 | |
1761 | \note This function is only available on Unix platforms. |
1762 | |
1763 | \sa childProcessModifier() |
1764 | */ |
1765 | auto QProcess::unixProcessParameters() const noexcept -> UnixProcessParameters |
1766 | { |
1767 | Q_D(const QProcess); |
1768 | return d->unixExtras ? d->unixExtras->processParameters : UnixProcessParameters{}; |
1769 | } |
1770 | |
1771 | /*! |
1772 | \since 6.6 |
1773 | Sets the extra settings and parameters for the child process on Unix |
1774 | systems to be \a params. This function can be used to ask QProcess to |
1775 | modify the child process before launching the target executable. |
1776 | |
1777 | This function can be used to change certain properties of the child |
1778 | process, such as closing all extraneous file descriptors, changing the nice |
1779 | level of the child, or disconnecting from the controlling TTY. For more |
1780 | fine-grained control of the child process or to modify it in other ways, |
1781 | use the setChildProcessModifier() function. If both a child process |
1782 | modifier and Unix process parameters are set, the modifier is run before |
1783 | these parameters are applied. |
1784 | |
1785 | \note This function is only available on Unix platforms. |
1786 | |
1787 | \sa unixProcessParameters(), setChildProcessModifier() |
1788 | */ |
1789 | void QProcess::setUnixProcessParameters(const UnixProcessParameters ¶ms) |
1790 | { |
1791 | Q_D(QProcess); |
1792 | if (!d->unixExtras) |
1793 | d->unixExtras.reset(p: new QProcessPrivate::UnixExtras); |
1794 | d->unixExtras->processParameters = params; |
1795 | } |
1796 | |
1797 | /*! |
1798 | \since 6.6 |
1799 | \overload |
1800 | |
1801 | Sets the extra settings for the child process on Unix systems to \a |
1802 | flagsOnly. This is the same as the overload with just the \c flags field |
1803 | set. |
1804 | \note This function is only available on Unix platforms. |
1805 | |
1806 | \sa unixProcessParameters(), setChildProcessModifier() |
1807 | */ |
1808 | void QProcess::setUnixProcessParameters(UnixProcessFlags flagsOnly) |
1809 | { |
1810 | Q_D(QProcess); |
1811 | if (!d->unixExtras) |
1812 | d->unixExtras.reset(p: new QProcessPrivate::UnixExtras); |
1813 | d->unixExtras->processParameters = { .flags: flagsOnly }; |
1814 | } |
1815 | #endif |
1816 | |
1817 | /*! |
1818 | If QProcess has been assigned a working directory, this function returns |
1819 | the working directory that the QProcess will enter before the program has |
1820 | started. Otherwise, (i.e., no directory has been assigned,) an empty |
1821 | string is returned, and QProcess will use the application's current |
1822 | working directory instead. |
1823 | |
1824 | \sa setWorkingDirectory() |
1825 | */ |
1826 | QString QProcess::workingDirectory() const |
1827 | { |
1828 | Q_D(const QProcess); |
1829 | return d->workingDirectory; |
1830 | } |
1831 | |
1832 | /*! |
1833 | Sets the working directory to \a dir. QProcess will start the |
1834 | process in this directory. The default behavior is to start the |
1835 | process in the working directory of the calling process. |
1836 | |
1837 | \sa workingDirectory(), start() |
1838 | */ |
1839 | void QProcess::setWorkingDirectory(const QString &dir) |
1840 | { |
1841 | Q_D(QProcess); |
1842 | d->workingDirectory = dir; |
1843 | } |
1844 | |
1845 | /*! |
1846 | \since 5.3 |
1847 | |
1848 | Returns the native process identifier for the running process, if |
1849 | available. If no process is currently running, \c 0 is returned. |
1850 | */ |
1851 | qint64 QProcess::processId() const |
1852 | { |
1853 | Q_D(const QProcess); |
1854 | #ifdef Q_OS_WIN |
1855 | return d->pid ? d->pid->dwProcessId : 0; |
1856 | #else |
1857 | return d->pid; |
1858 | #endif |
1859 | } |
1860 | |
1861 | /*! |
1862 | Closes all communication with the process and kills it. After calling this |
1863 | function, QProcess will no longer emit readyRead(), and data can no |
1864 | longer be read or written. |
1865 | */ |
1866 | void QProcess::close() |
1867 | { |
1868 | Q_D(QProcess); |
1869 | emit aboutToClose(); |
1870 | while (waitForBytesWritten(msecs: -1)) |
1871 | ; |
1872 | kill(); |
1873 | waitForFinished(msecs: -1); |
1874 | d->setWriteChannelCount(0); |
1875 | QIODevice::close(); |
1876 | } |
1877 | |
1878 | /*! \reimp |
1879 | */ |
1880 | bool QProcess::isSequential() const |
1881 | { |
1882 | return true; |
1883 | } |
1884 | |
1885 | /*! \reimp |
1886 | */ |
1887 | qint64 QProcess::bytesToWrite() const |
1888 | { |
1889 | #ifdef Q_OS_WIN |
1890 | return d_func()->pipeWriterBytesToWrite(); |
1891 | #else |
1892 | return QIODevice::bytesToWrite(); |
1893 | #endif |
1894 | } |
1895 | |
1896 | /*! |
1897 | Returns the type of error that occurred last. |
1898 | |
1899 | \sa state() |
1900 | */ |
1901 | QProcess::ProcessError QProcess::error() const |
1902 | { |
1903 | Q_D(const QProcess); |
1904 | return ProcessError(d->processError); |
1905 | } |
1906 | |
1907 | /*! |
1908 | Returns the current state of the process. |
1909 | |
1910 | \sa stateChanged(), error() |
1911 | */ |
1912 | QProcess::ProcessState QProcess::state() const |
1913 | { |
1914 | Q_D(const QProcess); |
1915 | return ProcessState(d->processState); |
1916 | } |
1917 | |
1918 | /*! |
1919 | \deprecated |
1920 | Sets the environment that QProcess will pass to the child process. |
1921 | The parameter \a environment is a list of key=value pairs. |
1922 | |
1923 | For example, the following code adds the environment variable \c{TMPDIR}: |
1924 | |
1925 | \snippet qprocess-environment/main.cpp 0 |
1926 | |
1927 | \note This function is less efficient than the setProcessEnvironment() |
1928 | function. |
1929 | |
1930 | \sa environment(), setProcessEnvironment(), systemEnvironment() |
1931 | */ |
1932 | void QProcess::setEnvironment(const QStringList &environment) |
1933 | { |
1934 | setProcessEnvironment(QProcessEnvironmentPrivate::fromList(list: environment)); |
1935 | } |
1936 | |
1937 | /*! |
1938 | \deprecated |
1939 | Returns the environment that QProcess will pass to its child |
1940 | process, or an empty QStringList if no environment has been set |
1941 | using setEnvironment(). If no environment has been set, the |
1942 | environment of the calling process will be used. |
1943 | |
1944 | \sa processEnvironment(), setEnvironment(), systemEnvironment() |
1945 | */ |
1946 | QStringList QProcess::environment() const |
1947 | { |
1948 | Q_D(const QProcess); |
1949 | return d->environment.toStringList(); |
1950 | } |
1951 | |
1952 | /*! |
1953 | \since 4.6 |
1954 | Sets the \a environment that QProcess will pass to the child process. |
1955 | |
1956 | For example, the following code adds the environment variable \c{TMPDIR}: |
1957 | |
1958 | \snippet qprocess-environment/main.cpp 1 |
1959 | |
1960 | Note how, on Windows, environment variable names are case-insensitive. |
1961 | |
1962 | \sa processEnvironment(), QProcessEnvironment::systemEnvironment(), |
1963 | {Environment variables} |
1964 | */ |
1965 | void QProcess::setProcessEnvironment(const QProcessEnvironment &environment) |
1966 | { |
1967 | Q_D(QProcess); |
1968 | d->environment = environment; |
1969 | } |
1970 | |
1971 | /*! |
1972 | \since 4.6 |
1973 | Returns the environment that QProcess will pass to its child process. If no |
1974 | environment has been set using setProcessEnvironment(), this method returns |
1975 | an object indicating the environment will be inherited from the parent. |
1976 | |
1977 | \sa setProcessEnvironment(), QProcessEnvironment::inheritsFromParent(), |
1978 | {Environment variables} |
1979 | */ |
1980 | QProcessEnvironment QProcess::processEnvironment() const |
1981 | { |
1982 | Q_D(const QProcess); |
1983 | return d->environment; |
1984 | } |
1985 | |
1986 | /*! |
1987 | Blocks until the process has started and the started() signal has |
1988 | been emitted, or until \a msecs milliseconds have passed. |
1989 | |
1990 | Returns \c true if the process was started successfully; otherwise |
1991 | returns \c false (if the operation timed out or if an error |
1992 | occurred). If the process had already started successfully before this |
1993 | function, it returns immediately. |
1994 | |
1995 | This function can operate without an event loop. It is |
1996 | useful when writing non-GUI applications and when performing |
1997 | I/O operations in a non-GUI thread. |
1998 | |
1999 | \warning Calling this function from the main (GUI) thread |
2000 | might cause your user interface to freeze. |
2001 | |
2002 | If msecs is -1, this function will not time out. |
2003 | |
2004 | \sa started(), waitForReadyRead(), waitForBytesWritten(), waitForFinished() |
2005 | */ |
2006 | bool QProcess::waitForStarted(int msecs) |
2007 | { |
2008 | Q_D(QProcess); |
2009 | if (d->processState == QProcess::Starting) |
2010 | return d->waitForStarted(deadline: QDeadlineTimer(msecs)); |
2011 | |
2012 | return d->processState == QProcess::Running; |
2013 | } |
2014 | |
2015 | /*! \reimp |
2016 | */ |
2017 | bool QProcess::waitForReadyRead(int msecs) |
2018 | { |
2019 | Q_D(QProcess); |
2020 | |
2021 | if (d->processState == QProcess::NotRunning) |
2022 | return false; |
2023 | if (d->currentReadChannel == QProcess::StandardOutput && d->stdoutChannel.closed) |
2024 | return false; |
2025 | if (d->currentReadChannel == QProcess::StandardError && d->stderrChannel.closed) |
2026 | return false; |
2027 | |
2028 | QDeadlineTimer deadline(msecs); |
2029 | if (d->processState == QProcess::Starting) { |
2030 | bool started = d->waitForStarted(deadline); |
2031 | if (!started) |
2032 | return false; |
2033 | } |
2034 | |
2035 | return d->waitForReadyRead(deadline); |
2036 | } |
2037 | |
2038 | /*! \reimp |
2039 | */ |
2040 | bool QProcess::waitForBytesWritten(int msecs) |
2041 | { |
2042 | Q_D(QProcess); |
2043 | if (d->processState == QProcess::NotRunning) |
2044 | return false; |
2045 | |
2046 | QDeadlineTimer deadline(msecs); |
2047 | if (d->processState == QProcess::Starting) { |
2048 | bool started = d->waitForStarted(deadline); |
2049 | if (!started) |
2050 | return false; |
2051 | } |
2052 | |
2053 | return d->waitForBytesWritten(deadline); |
2054 | } |
2055 | |
2056 | /*! |
2057 | Blocks until the process has finished and the finished() signal |
2058 | has been emitted, or until \a msecs milliseconds have passed. |
2059 | |
2060 | Returns \c true if the process finished; otherwise returns \c false (if |
2061 | the operation timed out, if an error occurred, or if this QProcess |
2062 | is already finished). |
2063 | |
2064 | This function can operate without an event loop. It is |
2065 | useful when writing non-GUI applications and when performing |
2066 | I/O operations in a non-GUI thread. |
2067 | |
2068 | \warning Calling this function from the main (GUI) thread |
2069 | might cause your user interface to freeze. |
2070 | |
2071 | If msecs is -1, this function will not time out. |
2072 | |
2073 | \sa finished(), waitForStarted(), waitForReadyRead(), waitForBytesWritten() |
2074 | */ |
2075 | bool QProcess::waitForFinished(int msecs) |
2076 | { |
2077 | Q_D(QProcess); |
2078 | if (d->processState == QProcess::NotRunning) |
2079 | return false; |
2080 | |
2081 | QDeadlineTimer deadline(msecs); |
2082 | if (d->processState == QProcess::Starting) { |
2083 | bool started = d->waitForStarted(deadline); |
2084 | if (!started) |
2085 | return false; |
2086 | } |
2087 | |
2088 | return d->waitForFinished(deadline); |
2089 | } |
2090 | |
2091 | /*! |
2092 | Sets the current state of the QProcess to the \a state specified. |
2093 | |
2094 | \sa state() |
2095 | */ |
2096 | void QProcess::setProcessState(ProcessState state) |
2097 | { |
2098 | Q_D(QProcess); |
2099 | if (d->processState == state) |
2100 | return; |
2101 | d->processState = state; |
2102 | emit stateChanged(state, QPrivateSignal()); |
2103 | } |
2104 | |
2105 | #if QT_VERSION < QT_VERSION_CHECK(7,0,0) |
2106 | /*! |
2107 | \internal |
2108 | */ |
2109 | auto QProcess::setupChildProcess() -> Use_setChildProcessModifier_Instead |
2110 | { |
2111 | Q_UNREACHABLE_RETURN({}); |
2112 | } |
2113 | #endif |
2114 | |
2115 | /*! \reimp |
2116 | */ |
2117 | qint64 QProcess::readData(char *data, qint64 maxlen) |
2118 | { |
2119 | Q_D(QProcess); |
2120 | Q_UNUSED(data); |
2121 | if (!maxlen) |
2122 | return 0; |
2123 | if (d->processState == QProcess::NotRunning) |
2124 | return -1; // EOF |
2125 | return 0; |
2126 | } |
2127 | |
2128 | /*! |
2129 | Regardless of the current read channel, this function returns all |
2130 | data available from the standard output of the process as a |
2131 | QByteArray. |
2132 | |
2133 | \sa readyReadStandardOutput(), readAllStandardError(), readChannel(), setReadChannel() |
2134 | */ |
2135 | QByteArray QProcess::readAllStandardOutput() |
2136 | { |
2137 | ProcessChannel tmp = readChannel(); |
2138 | setReadChannel(StandardOutput); |
2139 | QByteArray data = readAll(); |
2140 | setReadChannel(tmp); |
2141 | return data; |
2142 | } |
2143 | |
2144 | /*! |
2145 | Regardless of the current read channel, this function returns all |
2146 | data available from the standard error of the process as a |
2147 | QByteArray. |
2148 | |
2149 | \sa readyReadStandardError(), readAllStandardOutput(), readChannel(), setReadChannel() |
2150 | */ |
2151 | QByteArray QProcess::readAllStandardError() |
2152 | { |
2153 | Q_D(QProcess); |
2154 | QByteArray data; |
2155 | if (d->processChannelMode == MergedChannels) { |
2156 | qWarning(msg: "QProcess::readAllStandardError: Called with MergedChannels" ); |
2157 | } else { |
2158 | ProcessChannel tmp = readChannel(); |
2159 | setReadChannel(StandardError); |
2160 | data = readAll(); |
2161 | setReadChannel(tmp); |
2162 | } |
2163 | return data; |
2164 | } |
2165 | |
2166 | /*! |
2167 | Starts the given \a program in a new process, passing the command line |
2168 | arguments in \a arguments. See setProgram() for information about how |
2169 | QProcess searches for the executable to be run. The OpenMode is set to \a |
2170 | mode. No further splitting of the arguments is performed. |
2171 | |
2172 | The QProcess object will immediately enter the Starting state. If the |
2173 | process starts successfully, QProcess will emit started(); otherwise, |
2174 | errorOccurred() will be emitted. Do note that on platforms that are able to |
2175 | start child processes synchronously (notably Windows), those signals will |
2176 | be emitted before this function returns and this QProcess object will |
2177 | transition to either QProcess::Running or QProcess::NotRunning state, |
2178 | respectively. On others paltforms, the started() and errorOccurred() |
2179 | signals will be delayed. |
2180 | |
2181 | Call waitForStarted() to make sure the process has started (or has failed |
2182 | to start) and those signals have been emitted. It is safe to call that |
2183 | function even if the process starting state is already known, though the |
2184 | signal will not be emitted again. |
2185 | |
2186 | \b{Windows:} The arguments are quoted and joined into a command line |
2187 | that is compatible with the \c CommandLineToArgvW() Windows function. |
2188 | For programs that have different command line quoting requirements, |
2189 | you need to use setNativeArguments(). One notable program that does |
2190 | not follow the \c CommandLineToArgvW() rules is cmd.exe and, by |
2191 | consequence, all batch scripts. |
2192 | |
2193 | If the QProcess object is already running a process, a warning may be |
2194 | printed at the console, and the existing process will continue running |
2195 | unaffected. |
2196 | |
2197 | \note Success at starting the child process only implies the operating |
2198 | system has successfully created the process and assigned the resources |
2199 | every process has, such as its process ID. The child process may crash or |
2200 | otherwise fail very early and thus not produce its expected output. On most |
2201 | operating systems, this may include dynamic linking errors. |
2202 | |
2203 | \sa processId(), started(), waitForStarted(), setNativeArguments() |
2204 | */ |
2205 | void QProcess::start(const QString &program, const QStringList &arguments, OpenMode mode) |
2206 | { |
2207 | Q_D(QProcess); |
2208 | if (d->processState != NotRunning) { |
2209 | qWarning(msg: "QProcess::start: Process is already running" ); |
2210 | return; |
2211 | } |
2212 | if (program.isEmpty()) { |
2213 | d->setErrorAndEmit(error: QProcess::FailedToStart, description: tr(s: "No program defined" )); |
2214 | return; |
2215 | } |
2216 | |
2217 | d->program = program; |
2218 | d->arguments = arguments; |
2219 | |
2220 | d->start(mode); |
2221 | } |
2222 | |
2223 | /*! |
2224 | \since 5.1 |
2225 | \overload |
2226 | |
2227 | Starts the program set by setProgram() with arguments set by setArguments(). |
2228 | The OpenMode is set to \a mode. |
2229 | |
2230 | \sa open(), setProgram(), setArguments() |
2231 | */ |
2232 | void QProcess::start(OpenMode mode) |
2233 | { |
2234 | Q_D(QProcess); |
2235 | if (d->processState != NotRunning) { |
2236 | qWarning(msg: "QProcess::start: Process is already running" ); |
2237 | return; |
2238 | } |
2239 | if (d->program.isEmpty()) { |
2240 | d->setErrorAndEmit(error: QProcess::FailedToStart, description: tr(s: "No program defined" )); |
2241 | return; |
2242 | } |
2243 | |
2244 | d->start(mode); |
2245 | } |
2246 | |
2247 | /*! |
2248 | \since 6.0 |
2249 | |
2250 | Starts the command \a command in a new process. |
2251 | The OpenMode is set to \a mode. |
2252 | |
2253 | \a command is a single string of text containing both the program name |
2254 | and its arguments. The arguments are separated by one or more spaces. |
2255 | For example: |
2256 | |
2257 | \snippet code/src_corelib_io_qprocess.cpp 5 |
2258 | |
2259 | Arguments containing spaces must be quoted to be correctly supplied to |
2260 | the new process. For example: |
2261 | |
2262 | \snippet code/src_corelib_io_qprocess.cpp 6 |
2263 | |
2264 | Literal quotes in the \a command string are represented by triple quotes. |
2265 | For example: |
2266 | |
2267 | \snippet code/src_corelib_io_qprocess.cpp 7 |
2268 | |
2269 | After the \a command string has been split and unquoted, this function |
2270 | behaves like start(). |
2271 | |
2272 | On operating systems where the system API for passing command line |
2273 | arguments to a subprocess natively uses a single string (Windows), one can |
2274 | conceive command lines which cannot be passed via QProcess's portable |
2275 | list-based API. In these rare cases you need to use setProgram() and |
2276 | setNativeArguments() instead of this function. |
2277 | |
2278 | \sa splitCommand() |
2279 | \sa start() |
2280 | */ |
2281 | void QProcess::startCommand(const QString &command, OpenMode mode) |
2282 | { |
2283 | QStringList args = splitCommand(command); |
2284 | if (args.isEmpty()) { |
2285 | qWarning(msg: "QProcess::startCommand: empty or whitespace-only command was provided" ); |
2286 | return; |
2287 | } |
2288 | const QString program = args.takeFirst(); |
2289 | start(program, arguments: args, mode); |
2290 | } |
2291 | |
2292 | /*! |
2293 | \since 5.10 |
2294 | |
2295 | Starts the program set by setProgram() with arguments set by setArguments() |
2296 | in a new process, and detaches from it. Returns \c true on success; |
2297 | otherwise returns \c false. If the calling process exits, the |
2298 | detached process will continue to run unaffected. |
2299 | |
2300 | \b{Unix:} The started process will run in its own session and act |
2301 | like a daemon. |
2302 | |
2303 | The process will be started in the directory set by setWorkingDirectory(). |
2304 | If workingDirectory() is empty, the working directory is inherited |
2305 | from the calling process. |
2306 | |
2307 | If the function is successful then *\a pid is set to the process identifier |
2308 | of the started process; otherwise, it's set to -1. Note that the child |
2309 | process may exit and the PID may become invalid without notice. |
2310 | Furthermore, after the child process exits, the same PID may be recycled |
2311 | and used by a completely different process. User code should be careful |
2312 | when using this variable, especially if one intends to forcibly terminate |
2313 | the process by operating system means. |
2314 | |
2315 | Only the following property setters are supported by startDetached(): |
2316 | \list |
2317 | \li setArguments() |
2318 | \li setCreateProcessArgumentsModifier() |
2319 | \li setNativeArguments() |
2320 | \li setProcessEnvironment() |
2321 | \li setProgram() |
2322 | \li setStandardErrorFile() |
2323 | \li setStandardInputFile() |
2324 | \li setStandardOutputFile() |
2325 | \li setProcessChannelMode(QProcess::MergedChannels) |
2326 | \li setStandardOutputProcess() |
2327 | \li setWorkingDirectory() |
2328 | \endlist |
2329 | All other properties of the QProcess object are ignored. |
2330 | |
2331 | \note The called process inherits the console window of the calling |
2332 | process. To suppress console output, redirect standard/error output to |
2333 | QProcess::nullDevice(). |
2334 | |
2335 | \sa start() |
2336 | \sa startDetached(const QString &program, const QStringList &arguments, |
2337 | const QString &workingDirectory, qint64 *pid) |
2338 | */ |
2339 | bool QProcess::startDetached(qint64 *pid) |
2340 | { |
2341 | Q_D(QProcess); |
2342 | if (d->processState != NotRunning) { |
2343 | qWarning(msg: "QProcess::startDetached: Process is already running" ); |
2344 | return false; |
2345 | } |
2346 | if (d->program.isEmpty()) { |
2347 | d->setErrorAndEmit(error: QProcess::FailedToStart, description: tr(s: "No program defined" )); |
2348 | return false; |
2349 | } |
2350 | return d->startDetached(pPid: pid); |
2351 | } |
2352 | |
2353 | /*! |
2354 | Starts the program set by setProgram() with arguments set by setArguments(). |
2355 | The OpenMode is set to \a mode. |
2356 | |
2357 | This method is an alias for start(), and exists only to fully implement |
2358 | the interface defined by QIODevice. |
2359 | |
2360 | Returns \c true if the program has been started. |
2361 | |
2362 | \sa start(), setProgram(), setArguments() |
2363 | */ |
2364 | bool QProcess::open(OpenMode mode) |
2365 | { |
2366 | Q_D(QProcess); |
2367 | if (d->processState != NotRunning) { |
2368 | qWarning(msg: "QProcess::start: Process is already running" ); |
2369 | return false; |
2370 | } |
2371 | if (d->program.isEmpty()) { |
2372 | qWarning(msg: "QProcess::start: program not set" ); |
2373 | return false; |
2374 | } |
2375 | |
2376 | d->start(mode); |
2377 | return true; |
2378 | } |
2379 | |
2380 | void QProcessPrivate::start(QIODevice::OpenMode mode) |
2381 | { |
2382 | Q_Q(QProcess); |
2383 | #if defined QPROCESS_DEBUG |
2384 | qDebug() << "QProcess::start(" << program << ',' << arguments << ',' << mode << ')'; |
2385 | #endif |
2386 | |
2387 | if (stdinChannel.type != QProcessPrivate::Channel::Normal) |
2388 | mode &= ~QIODevice::WriteOnly; // not open for writing |
2389 | if (stdoutChannel.type != QProcessPrivate::Channel::Normal && |
2390 | (stderrChannel.type != QProcessPrivate::Channel::Normal || |
2391 | processChannelMode == QProcess::MergedChannels)) |
2392 | mode &= ~QIODevice::ReadOnly; // not open for reading |
2393 | if (mode == 0) |
2394 | mode = QIODevice::Unbuffered; |
2395 | if ((mode & QIODevice::ReadOnly) == 0) { |
2396 | if (stdoutChannel.type == QProcessPrivate::Channel::Normal) |
2397 | q->setStandardOutputFile(fileName: q->nullDevice()); |
2398 | if (stderrChannel.type == QProcessPrivate::Channel::Normal |
2399 | && processChannelMode != QProcess::MergedChannels) |
2400 | q->setStandardErrorFile(fileName: q->nullDevice()); |
2401 | } |
2402 | |
2403 | q->QIODevice::open(mode); |
2404 | |
2405 | if (q->isReadable() && processChannelMode != QProcess::MergedChannels) |
2406 | setReadChannelCount(2); |
2407 | |
2408 | stdinChannel.closed = false; |
2409 | stdoutChannel.closed = false; |
2410 | stderrChannel.closed = false; |
2411 | |
2412 | exitCode = 0; |
2413 | exitStatus = QProcess::NormalExit; |
2414 | processError = QProcess::UnknownError; |
2415 | errorString.clear(); |
2416 | startProcess(); |
2417 | } |
2418 | |
2419 | /*! |
2420 | \since 5.15 |
2421 | |
2422 | Splits the string \a command into a list of tokens, and returns |
2423 | the list. |
2424 | |
2425 | Tokens with spaces can be surrounded by double quotes; three |
2426 | consecutive double quotes represent the quote character itself. |
2427 | */ |
2428 | QStringList QProcess::splitCommand(QStringView command) |
2429 | { |
2430 | QStringList args; |
2431 | QString tmp; |
2432 | int quoteCount = 0; |
2433 | bool inQuote = false; |
2434 | |
2435 | // handle quoting. tokens can be surrounded by double quotes |
2436 | // "hello world". three consecutive double quotes represent |
2437 | // the quote character itself. |
2438 | for (int i = 0; i < command.size(); ++i) { |
2439 | if (command.at(n: i) == u'"') { |
2440 | ++quoteCount; |
2441 | if (quoteCount == 3) { |
2442 | // third consecutive quote |
2443 | quoteCount = 0; |
2444 | tmp += command.at(n: i); |
2445 | } |
2446 | continue; |
2447 | } |
2448 | if (quoteCount) { |
2449 | if (quoteCount == 1) |
2450 | inQuote = !inQuote; |
2451 | quoteCount = 0; |
2452 | } |
2453 | if (!inQuote && command.at(n: i).isSpace()) { |
2454 | if (!tmp.isEmpty()) { |
2455 | args += tmp; |
2456 | tmp.clear(); |
2457 | } |
2458 | } else { |
2459 | tmp += command.at(n: i); |
2460 | } |
2461 | } |
2462 | if (!tmp.isEmpty()) |
2463 | args += tmp; |
2464 | |
2465 | return args; |
2466 | } |
2467 | |
2468 | /*! |
2469 | \since 5.0 |
2470 | |
2471 | Returns the program the process was last started with. |
2472 | |
2473 | \sa start() |
2474 | */ |
2475 | QString QProcess::program() const |
2476 | { |
2477 | Q_D(const QProcess); |
2478 | return d->program; |
2479 | } |
2480 | |
2481 | /*! |
2482 | \since 5.1 |
2483 | |
2484 | Set the \a program to use when starting the process. |
2485 | This function must be called before start(). |
2486 | |
2487 | If \a program is an absolute path, it specifies the exact executable that |
2488 | will be launched. Relative paths will be resolved in a platform-specific |
2489 | manner, which includes searching the \c PATH environment variable (see |
2490 | \l{Finding the Executable} for details). |
2491 | |
2492 | \sa start(), setArguments(), program(), QStandardPaths::findExecutable() |
2493 | */ |
2494 | void QProcess::setProgram(const QString &program) |
2495 | { |
2496 | Q_D(QProcess); |
2497 | if (d->processState != NotRunning) { |
2498 | qWarning(msg: "QProcess::setProgram: Process is already running" ); |
2499 | return; |
2500 | } |
2501 | d->program = program; |
2502 | } |
2503 | |
2504 | /*! |
2505 | \since 5.0 |
2506 | |
2507 | Returns the command line arguments the process was last started with. |
2508 | |
2509 | \sa start() |
2510 | */ |
2511 | QStringList QProcess::arguments() const |
2512 | { |
2513 | Q_D(const QProcess); |
2514 | return d->arguments; |
2515 | } |
2516 | |
2517 | /*! |
2518 | \since 5.1 |
2519 | |
2520 | Set the \a arguments to pass to the called program when starting the process. |
2521 | This function must be called before start(). |
2522 | |
2523 | \sa start(), setProgram(), arguments() |
2524 | */ |
2525 | void QProcess::setArguments(const QStringList &arguments) |
2526 | { |
2527 | Q_D(QProcess); |
2528 | if (d->processState != NotRunning) { |
2529 | qWarning(msg: "QProcess::setProgram: Process is already running" ); |
2530 | return; |
2531 | } |
2532 | d->arguments = arguments; |
2533 | } |
2534 | |
2535 | /*! |
2536 | Attempts to terminate the process. |
2537 | |
2538 | The process may not exit as a result of calling this function (it is given |
2539 | the chance to prompt the user for any unsaved files, etc). |
2540 | |
2541 | On Windows, terminate() posts a WM_CLOSE message to all top-level windows |
2542 | of the process and then to the main thread of the process itself. On Unix |
2543 | and \macos the \c SIGTERM signal is sent. |
2544 | |
2545 | Console applications on Windows that do not run an event loop, or whose |
2546 | event loop does not handle the WM_CLOSE message, can only be terminated by |
2547 | calling kill(). |
2548 | |
2549 | \sa kill() |
2550 | */ |
2551 | void QProcess::terminate() |
2552 | { |
2553 | Q_D(QProcess); |
2554 | d->terminateProcess(); |
2555 | } |
2556 | |
2557 | /*! |
2558 | Kills the current process, causing it to exit immediately. |
2559 | |
2560 | On Windows, kill() uses TerminateProcess, and on Unix and \macos, the |
2561 | SIGKILL signal is sent to the process. |
2562 | |
2563 | \sa terminate() |
2564 | */ |
2565 | void QProcess::kill() |
2566 | { |
2567 | Q_D(QProcess); |
2568 | d->killProcess(); |
2569 | } |
2570 | |
2571 | /*! |
2572 | Returns the exit code of the last process that finished. |
2573 | |
2574 | This value is not valid unless exitStatus() returns NormalExit. |
2575 | */ |
2576 | int QProcess::exitCode() const |
2577 | { |
2578 | Q_D(const QProcess); |
2579 | return d->exitCode; |
2580 | } |
2581 | |
2582 | /*! |
2583 | \since 4.1 |
2584 | |
2585 | Returns the exit status of the last process that finished. |
2586 | |
2587 | On Windows, if the process was terminated with TerminateProcess() from |
2588 | another application, this function will still return NormalExit |
2589 | unless the exit code is less than 0. |
2590 | */ |
2591 | QProcess::ExitStatus QProcess::exitStatus() const |
2592 | { |
2593 | Q_D(const QProcess); |
2594 | return ExitStatus(d->exitStatus); |
2595 | } |
2596 | |
2597 | /*! |
2598 | Starts the program \a program with the arguments \a arguments in a |
2599 | new process, waits for it to finish, and then returns the exit |
2600 | code of the process. Any data the new process writes to the |
2601 | console is forwarded to the calling process. |
2602 | |
2603 | The environment and working directory are inherited from the calling |
2604 | process. |
2605 | |
2606 | Argument handling is identical to the respective start() overload. |
2607 | |
2608 | If the process cannot be started, -2 is returned. If the process |
2609 | crashes, -1 is returned. Otherwise, the process' exit code is |
2610 | returned. |
2611 | |
2612 | \sa start() |
2613 | */ |
2614 | int QProcess::execute(const QString &program, const QStringList &arguments) |
2615 | { |
2616 | QProcess process; |
2617 | process.setProcessChannelMode(ForwardedChannels); |
2618 | process.start(program, arguments); |
2619 | if (!process.waitForFinished(msecs: -1) || process.error() == FailedToStart) |
2620 | return -2; |
2621 | return process.exitStatus() == QProcess::NormalExit ? process.exitCode() : -1; |
2622 | } |
2623 | |
2624 | /*! |
2625 | \overload startDetached() |
2626 | |
2627 | Starts the program \a program with the arguments \a arguments in a |
2628 | new process, and detaches from it. Returns \c true on success; |
2629 | otherwise returns \c false. If the calling process exits, the |
2630 | detached process will continue to run unaffected. |
2631 | |
2632 | Argument handling is identical to the respective start() overload. |
2633 | |
2634 | The process will be started in the directory \a workingDirectory. |
2635 | If \a workingDirectory is empty, the working directory is inherited |
2636 | from the calling process. |
2637 | |
2638 | If the function is successful then *\a pid is set to the process |
2639 | identifier of the started process. |
2640 | |
2641 | \sa start() |
2642 | */ |
2643 | bool QProcess::startDetached(const QString &program, |
2644 | const QStringList &arguments, |
2645 | const QString &workingDirectory, |
2646 | qint64 *pid) |
2647 | { |
2648 | QProcess process; |
2649 | process.setProgram(program); |
2650 | process.setArguments(arguments); |
2651 | process.setWorkingDirectory(workingDirectory); |
2652 | return process.startDetached(pid); |
2653 | } |
2654 | |
2655 | /*! |
2656 | \since 4.1 |
2657 | |
2658 | Returns the environment of the calling process as a list of |
2659 | key=value pairs. Example: |
2660 | |
2661 | \snippet code/src_corelib_io_qprocess.cpp 8 |
2662 | |
2663 | This function does not cache the system environment. Therefore, it's |
2664 | possible to obtain an updated version of the environment if low-level C |
2665 | library functions like \tt setenv or \tt putenv have been called. |
2666 | |
2667 | However, note that repeated calls to this function will recreate the |
2668 | list of environment variables, which is a non-trivial operation. |
2669 | |
2670 | \note For new code, it is recommended to use QProcessEnvironment::systemEnvironment() |
2671 | |
2672 | \sa QProcessEnvironment::systemEnvironment(), setProcessEnvironment() |
2673 | */ |
2674 | QStringList QProcess::systemEnvironment() |
2675 | { |
2676 | return QProcessEnvironment::systemEnvironment().toStringList(); |
2677 | } |
2678 | |
2679 | /*! |
2680 | \fn QProcessEnvironment QProcessEnvironment::systemEnvironment() |
2681 | |
2682 | \since 4.6 |
2683 | |
2684 | \brief The systemEnvironment function returns the environment of |
2685 | the calling process. |
2686 | |
2687 | It is returned as a QProcessEnvironment. This function does not |
2688 | cache the system environment. Therefore, it's possible to obtain |
2689 | an updated version of the environment if low-level C library |
2690 | functions like \tt setenv or \tt putenv have been called. |
2691 | |
2692 | However, note that repeated calls to this function will recreate the |
2693 | QProcessEnvironment object, which is a non-trivial operation. |
2694 | |
2695 | \sa QProcess::systemEnvironment() |
2696 | */ |
2697 | |
2698 | /*! |
2699 | \since 5.2 |
2700 | |
2701 | \brief The null device of the operating system. |
2702 | |
2703 | The returned file path uses native directory separators. |
2704 | |
2705 | \sa QProcess::setStandardInputFile(), QProcess::setStandardOutputFile(), |
2706 | QProcess::setStandardErrorFile() |
2707 | */ |
2708 | QString QProcess::nullDevice() |
2709 | { |
2710 | #ifdef Q_OS_WIN |
2711 | return QStringLiteral("\\\\.\\NUL" ); |
2712 | #elif defined(_PATH_DEVNULL) |
2713 | return QStringLiteral(_PATH_DEVNULL); |
2714 | #else |
2715 | return QStringLiteral("/dev/null" ); |
2716 | #endif |
2717 | } |
2718 | |
2719 | #endif // QT_CONFIG(process) |
2720 | |
2721 | QT_END_NAMESPACE |
2722 | |
2723 | #include "moc_qprocess.cpp" |
2724 | |