diff options
-rw-r--r-- | src/corelib/io/qprocess.cpp | 18 | ||||
-rw-r--r-- | tests/auto/corelib/io/qprocess/tst_qprocess.cpp | 8 |
2 files changed, 21 insertions, 5 deletions
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 976d8503f3..a7d521fc6c 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1078,6 +1078,17 @@ bool QProcessPrivate::_q_processDied() processError = QProcess::Crashed; q->setErrorString(QProcess::tr("Process crashed")); emit q->error(processError); + } else { +#ifdef QPROCESS_USE_SPAWN + // if we're using posix_spawn, waitForStarted always succeeds. + // POSIX documents that the sub-process launched by posix_spawn will exit with code + // 127 if anything prevents the target program from starting. + // http://pubs.opengroup.org/onlinepubs/009695399/functions/posix_spawn.html + if (exitStatus == QProcess::NormalExit && exitCode == 127) { + processError = QProcess::FailedToStart; + q->setErrorString(QProcess::tr("Process failed to start (spawned process exited with code 127)")); + } +#endif } bool wasRunning = (processState == QProcess::Running); @@ -1753,6 +1764,9 @@ QProcessEnvironment QProcess::processEnvironment() const If msecs is -1, this function will not time out. + \note On some UNIX operating systems, this function may return true but + the process may later report a QProcess::FailedToStart error. + \sa started(), waitForReadyRead(), waitForBytesWritten(), waitForFinished() */ bool QProcess::waitForStarted(int msecs) @@ -2347,7 +2361,7 @@ int QProcess::execute(const QString &program, const QStringList &arguments) QProcess process; process.setReadChannelMode(ForwardedChannels); process.start(program, arguments); - if (!process.waitForFinished(-1)) + if (!process.waitForFinished(-1) || process.error() == FailedToStart) return -2; return process.exitStatus() == QProcess::NormalExit ? process.exitCode() : -1; } @@ -2370,7 +2384,7 @@ int QProcess::execute(const QString &command) QProcess process; process.setReadChannelMode(ForwardedChannels); process.start(command); - if (!process.waitForFinished(-1)) + if (!process.waitForFinished(-1) || process.error() == FailedToStart) return -2; return process.exitStatus() == QProcess::NormalExit ? process.exitCode() : -1; } diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index 3866dd246b..a67d08da6f 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -317,9 +317,6 @@ void tst_QProcess::execute() { QCOMPARE(QProcess::execute("testProcessNormal/testProcessNormal", QStringList() << "arg1" << "arg2"), 0); -#ifdef QPROCESS_USE_SPAWN - QEXPECT_FAIL("", "QProcess cannot detect failure to start when using posix_spawn()", Continue); -#endif QCOMPARE(QProcess::execute("nonexistingexe"), -2); } @@ -1527,6 +1524,11 @@ void tst_QProcess::nativeArguments() void tst_QProcess::exitCodeTest() { for (int i = 0; i < 255; ++i) { +#ifdef QPROCESS_USE_SPAWN + // POSIX reserves exit code 127 when using posix_spawn + if (i == 127) + continue; +#endif QProcess process; process.start("testExitCodes/testExitCodes " + QString::number(i)); QVERIFY(process.waitForFinished(5000)); |