diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index ca65a3c776c..fcbce92ade4 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -1290,7 +1290,6 @@ void QProcessPrivate::waitForDeadChild() bool QProcessPrivate::startDetached(qint64 *pid) { AutoPipe startedPipe, pidPipe; - childStartedPipe[1] = startedPipe[1]; if (!startedPipe || !pidPipe) { setErrorAndEmit(QProcess::FailedToStart, "pipe: "_L1 + qt_error_string(errno)); return false; @@ -1309,6 +1308,7 @@ bool QProcessPrivate::startDetached(qint64 *pid) return false; } + childStartedPipe[1] = startedPipe[1]; // for failChildProcess() pid_t childPid = childProcess.doFork([&] { ::setsid(); @@ -1323,6 +1323,7 @@ bool QProcessPrivate::startDetached(qint64 *pid) qt_safe_write(pidPipe[1], &doubleForkPid, sizeof(pid_t)); return 0; }); + childStartedPipe[1] = -1; int savedErrno = errno; closeChannels(); diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index 46c25b90677..1056eaa107b 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -1488,6 +1488,9 @@ struct DisableCrashLogger } }; +QT_BEGIN_NAMESPACE +Q_AUTOTEST_EXPORT bool _qprocessUsingVfork() noexcept; +QT_END_NAMESPACE static constexpr char messageFromChildProcess[] = "Message from the child process"; static_assert(std::char_traits::length(messageFromChildProcess) <= PIPE_BUF); static void childProcessModifier(int fd) @@ -1499,17 +1502,28 @@ static void childProcessModifier(int fd) void tst_QProcess::setChildProcessModifier_data() { QTest::addColumn("detached"); - QTest::newRow("normal") << false; - QTest::newRow("detached") << true; + QTest::addColumn("useVfork"); + QTest::newRow("normal") << false << false; + QTest::newRow("detached") << true << false; + +#ifdef QT_BUILD_INTERNAL + if (_qprocessUsingVfork()) { + QTest::newRow("normal-vfork") << false << true; + QTest::newRow("detached-vfork") << true << true; + } +#endif } void tst_QProcess::setChildProcessModifier() { QFETCH(bool, detached); + QFETCH(bool, useVfork); int pipes[2] = { -1 , -1 }; QVERIFY(qt_safe_pipe(pipes) == 0); QProcess process; + if (useVfork) + process.setUnixProcessParameters(QProcess::UnixProcessFlag::UseVFork); process.setChildProcessModifier([pipes]() { ::childProcessModifier(pipes[1]); }); @@ -1542,7 +1556,11 @@ void tst_QProcess::failChildProcessModifier() "Implementation detail: the length of the message is limited"); QFETCH(bool, detached); + QFETCH(bool, useVfork); + QProcess process; + if (useVfork) + process.setUnixProcessParameters(QProcess::UnixProcessFlag::UseVFork); process.setChildProcessModifier([&process]() { process.failChildProcessModifier(failureMsg, EPERM); }); @@ -1651,9 +1669,6 @@ void tst_QProcess::terminateInChildProcessModifier() #endif } -QT_BEGIN_NAMESPACE -Q_AUTOTEST_EXPORT bool _qprocessUsingVfork() noexcept; -QT_END_NAMESPACE void tst_QProcess::raiseInChildProcessModifier() { #ifdef QT_BUILD_INTERNAL