| 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 |  |