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. Pick-to: 6.7.0 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>
This commit is contained in:
parent
a7a2cf8746
commit
a2d67a2671
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user