summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2023-03-17 13:31:36 -0700
committerThiago Macieira <thiago.macieira@intel.com>2023-05-22 10:43:53 -0700
commitc5221f6be00c16187e0abf008b33c230fea56c29 (patch)
treeb0032b37677d2b307e7d1589e1eb124285b76992 /tests
parentf9c87cfd44bcf4b90cb45354252ef19f647b0469 (diff)
QProcess/Linux: add a flag to re-enable the vfork()-like semantics
Commit 29b2fe40dc778ec73da7e5643fcfd8979d8ecebc disabled it by reverting commit d6bf71123d3ef073f25610345cb5dc920e4fb783. We now add the promised flag to opt-in. The flag is added to all Unix systems, but it really only applies to Linux right now. No ChangeLog because the whole UnixProcessParameters structure is new and has its own changelog. Task-number: QTBUG-104493 Task-number: QTBUG-111243 Task-number: QTBUG-111964 Change-Id: Icfe44ecf285a480fafe4fffd174d4effd3382495 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/io/qprocess/tst_qprocess.cpp18
1 files changed, 16 insertions, 2 deletions
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
index 069440c49b..540df04f73 100644
--- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
@@ -21,6 +21,7 @@
#include <qplatformdefs.h>
#ifdef Q_OS_UNIX
# include <private/qcore_unix_p.h>
+# include <sys/wait.h>
#endif
#include <QtTest/private/qemulationdetector_p.h>
@@ -157,6 +158,7 @@ protected slots:
private:
qint64 bytesAvailable;
QTemporaryDir m_temporaryDir;
+ bool haveWorkingVFork = false;
};
void tst_QProcess::initTestCase()
@@ -168,6 +170,12 @@ void tst_QProcess::initTestCase()
// chdir to our testdata path and execute helper apps relative to that.
QString testdata_dir = QFileInfo(QFINDTESTDATA("testProcessNormal")).absolutePath();
QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir));
+
+#if defined(Q_OS_LINUX) && QT_CONFIG(forkfd_pidfd)
+ // see detect_clone_pidfd_support() in forkfd_linux.c for explanation
+ waitid(/*P_PIDFD*/ idtype_t(3), INT_MAX, NULL, WEXITED|WNOHANG);
+ haveWorkingVFork = (errno == EBADF);
+#endif
}
void tst_QProcess::cleanupTestCase()
@@ -1515,6 +1523,7 @@ void tst_QProcess::unixProcessParametersAndChildModifier()
static constexpr char message[] = "Message from the handler function\n";
static_assert(std::char_traits<char>::length(message) <= PIPE_BUF);
QProcess process;
+ QAtomicInt vforkControl;
int pipes[2];
QVERIFY2(pipe(pipes) == 0, qPrintable(qt_error_string()));
@@ -1523,10 +1532,12 @@ void tst_QProcess::unixProcessParametersAndChildModifier()
auto pipeGuard1 = qScopeGuard([=] { close(pipes[1]); });
// verify that our modifier runs before the parameters are applied
- process.setChildProcessModifier([=] {
+ process.setChildProcessModifier([=, &vforkControl] {
write(pipes[1], message, strlen(message));
+ vforkControl.storeRelaxed(1);
});
- auto flags = QProcess::UnixProcessFlag::CloseNonStandardFileDescriptors;
+ auto flags = QProcess::UnixProcessFlag::CloseNonStandardFileDescriptors |
+ QProcess::UnixProcessFlag::UseVFork;
process.setUnixProcessParameters({ flags });
process.setProgram("testUnixProcessParameters/testUnixProcessParameters");
process.setArguments({ "std-file-descriptors", QString::number(pipes[1]) });
@@ -1542,6 +1553,9 @@ void tst_QProcess::unixProcessParametersAndChildModifier()
int r = read(pipes[0], buf, sizeof(buf));
QVERIFY2(r >= 0, qPrintable(qt_error_string()));
QCOMPARE(QByteArrayView(buf, r), message);
+
+ if (haveWorkingVFork)
+ QVERIFY2(vforkControl.loadRelaxed(), "QProcess doesn't appear to have used vfork()");
}
#endif