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