From 31bb141aed52549fae52f2156ac66bd2647cad16 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 18 Feb 2021 09:22:09 -0800 Subject: QProcess::startDetached/Unix: move up the chdir() and remove qWarning That qWarning cannot be in the child process (we don't know if a user logger is fork-no-exec-safe) and the failure to chdir() should be reported as a failure in QProcess::startDetached() instead. Change-Id: Ic90d8429a0eb4837971dfffd1664e7577c81610b Reviewed-by: Oswald Buddenhagen Reviewed-by: David Llewellyn-Jones --- src/corelib/io/qprocess_unix.cpp | 12 ++++++------ tests/auto/corelib/io/qprocess/tst_qprocess.cpp | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 3d223bb725..b6757e5b79 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -916,18 +916,18 @@ bool QProcessPrivate::startDetached(qint64 *pid) qt_safe_close(startedPipe[0]); qt_safe_close(pidPipe[0]); - pid_t doubleForkPid = fork(); + pid_t doubleForkPid = 0; + if (!encodedWorkingDirectory.isEmpty()) + doubleForkPid = QT_CHDIR(encodedWorkingDirectory.constData()); + + if (doubleForkPid == 0) + doubleForkPid = fork(); if (doubleForkPid == 0) { qt_safe_close(pidPipe[1]); // Render channels configuration. commitChannels(); - if (!encodedWorkingDirectory.isEmpty()) { - if (QT_CHDIR(encodedWorkingDirectory.constData()) == -1) - qWarning("QProcessPrivate::startDetached: failed to chdir to %s", encodedWorkingDirectory.constData()); - } - char **argv = new char *[arguments.size() + 2]; for (int i = 0; i < arguments.size(); ++i) argv[i + 1] = ::strdup(QFile::encodeName(arguments.at(i)).constData()); diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index 82a2cb1254..e68fccf4be 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -118,6 +118,7 @@ private slots: void discardUnwantedOutput(); void setWorkingDirectory(); void setNonExistentWorkingDirectory(); + void detachedSetNonExistentWorkingDirectory(); void exitStatus_data(); void exitStatus(); @@ -2266,6 +2267,20 @@ void tst_QProcess::setNonExistentWorkingDirectory() #endif } +void tst_QProcess::detachedSetNonExistentWorkingDirectory() +{ + QProcess process; + process.setWorkingDirectory("this/directory/should/not/exist/for/sure"); + + // use absolute path because on Windows, the executable is relative to the parent's CWD + // while on Unix with fork it's relative to the child's (with posix_spawn, it could be either). + process.setProgram(QFileInfo("testSetWorkingDirectory/testSetWorkingDirectory").absoluteFilePath()); + + qint64 pid = -1; + QVERIFY(!process.startDetached(&pid)); + QCOMPARE(pid, -1); +} + void tst_QProcess::startFinishStartFinish() { QProcess process; -- cgit v1.2.3