summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2024-03-11 09:55:10 -0700
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2024-03-14 07:24:47 +0000
commit0df3ff3d7067c5a57e51a49303f5558b48d348de (patch)
tree01351af9c78e4b58b8c0a2cf5eb5643692f2fda4
parent9057431efb886990cf633bbb304d18a1d624fe0e (diff)
QProcess/Unix: fix close() on invalid file descriptor
Commit 90bc0ad41f9937f9cba801b3166635f6f55e0678 ("QProcess/Unix: add failChildProcessModifier()") added this line that set childStartedPipe so that the failChildProcess() callback had something to write to. But we left it set on exit from QProcessPrivate::startDetached(), which caused the QProcess destructor to try and close it. Noticed when debugging the issue for QTBUG-123083. Task-number: QTBUG-123083 Change-Id: I6818d78a57394e37857bfffd17bbc41c8400270f Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit 0f56502fb6f062c6d2308198c93412c34525125b) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit a2d67a2671f8b2ab96d4b458d80972c2bd83b3db)
-rw-r--r--src/corelib/io/qprocess_unix.cpp3
-rw-r--r--tests/auto/corelib/io/qprocess/tst_qprocess.cpp25
2 files changed, 22 insertions, 6 deletions
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index ca65a3c776..fcbce92ade 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 46c25b9067..1056eaa107 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<char>::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<bool>("detached");
- QTest::newRow("normal") << false;
- QTest::newRow("detached") << true;
+ QTest::addColumn<bool>("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