summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2020-02-29 14:47:43 -0800
committerThiago Macieira <thiago.macieira@intel.com>2020-09-08 21:00:29 -0700
commit7e93870401852623b316a9e707baf67cbaa6d722 (patch)
treef26caef521e35e3c3b3827794ffea832d4fd0491 /tests/auto/corelib
parent3deb154d2207c5b38675ee75b4a843a100abf6a9 (diff)
QProcess/Unix: introduce setChildProcessModifier()
[ChangeLog][Source-Incompatible Changes] QProcess::setupChildProcess() was removed. To execute code in a child process, use QProcess::setChildProcessModifier() [ChangeLog][QtCore][QProcess] Added setChildProcessModifier() function with which one can provide code to be run in the Unix child process between fork() and execve(). With this function, it is no longer necessary to derive from QProcess in order to execute actions in the child process. Another reason is that we can tell whether the std::function carries a valid target much more easily than we can tell whether QProcess was overridden. The setupChildProcess() virtual function does not need to be marked final, since no overrider could ever return an inaccessible private class. This also makes sure the error presented to the user is about the return type, not about attempting to override a final. Clang: error: virtual function 'f' has a different return type ('void') than the function it overrides (which has return type 'QProcess::Use_setChildProcessModifier_Instead') GCC: error: conflicting return type specified for 'virtual void MyProcess::setupChildProcess()' note: overridden function is 'virtual QProcess::Use_setChildProcessModifier_Instead QProcess::setupChildProcess()' ICC: error: return type is neither identical to nor covariant with return type "QProcess::Use_setChildProcessModifier_Instead" of overridden virtual function "QProcess::setupChildProcess" MSVC is not relevant since it doesn't compile to Unix. Change-Id: Ia8b65350cd5d49debca9fffd15f801161363aea7 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r--tests/auto/corelib/io/qprocess/tst_qprocess.cpp47
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/externaltests.cpp32
2 files changed, 36 insertions, 43 deletions
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
index a7ecf6cae4..317db0574c 100644
--- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
@@ -63,7 +63,7 @@ private slots:
void getSetCheck();
void constructing();
void simpleStart();
- void setupChildProcess();
+ void setChildProcessModifier();
void startWithOpen();
void startWithOldOpen();
void execute();
@@ -267,49 +267,40 @@ void tst_QProcess::simpleStart()
QCOMPARE(qvariant_cast<QProcess::ProcessState>(spy.at(2).at(0)), QProcess::NotRunning);
}
-void tst_QProcess::setupChildProcess()
+static const char messageFromChildProcess[] = "Message from the child process";
+static void childProcessModifier(int fd)
{
- /* This test exists because in Qt 5.15, the Unix version of QProcess has
- * some code that depends on whether it's an actual QProcess or a
- * derived class */
- static const char setupChildMessage[] = "Called from setupChildProcess()";
- class DerivedProcessClass : public QProcess {
- public:
- int fd;
- DerivedProcessClass(int fd) : fd(fd)
- {
- }
-
- protected:
- void setupChildProcess() override
- {
- QT_WRITE(fd, setupChildMessage, sizeof(setupChildMessage) - 1);
- QT_CLOSE(fd);
- }
- };
+ QT_WRITE(fd, messageFromChildProcess, sizeof(messageFromChildProcess) - 1);
+ QT_CLOSE(fd);
+}
- int pipes[2] = { -1 , -1 };
+void tst_QProcess::setChildProcessModifier()
+{
#ifdef Q_OS_UNIX
+ int pipes[2] = { -1 , -1 };
QVERIFY(qt_safe_pipe(pipes) == 0);
-#endif
- DerivedProcessClass process(pipes[1]);
+ QProcess process;
+ process.setChildProcessModifier([pipes]() {
+ ::childProcessModifier(pipes[1]);
+ });
process.start("testProcessNormal/testProcessNormal");
if (process.state() != QProcess::Starting)
QCOMPARE(process.state(), QProcess::Running);
QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString()));
-#ifdef Q_OS_UNIX
- char buf[sizeof setupChildMessage] = {};
+ char buf[sizeof messageFromChildProcess] = {};
qt_safe_close(pipes[1]);
- QCOMPARE(qt_safe_read(pipes[0], buf, sizeof(buf)), qint64(sizeof(setupChildMessage) - 1));
- QCOMPARE(buf, setupChildMessage);
+ QCOMPARE(qt_safe_read(pipes[0], buf, sizeof(buf)), qint64(sizeof(messageFromChildProcess)) - 1);
+ QCOMPARE(buf, messageFromChildProcess);
qt_safe_close(pipes[0]);
-#endif
QVERIFY2(process.waitForFinished(5000), qPrintable(process.errorString()));
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
QCOMPARE(process.exitCode(), 0);
+#else
+ QSKIP("Unix-only test");
+#endif
}
void tst_QProcess::startWithOpen()
diff --git a/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp b/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp
index d1bb89f549..21ef6e8e35 100644
--- a/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp
+++ b/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp
@@ -86,26 +86,28 @@ namespace QTest {
}
}
+# ifdef Q_OS_UNIX
class QExternalProcess: public QProcess
{
- protected:
-#ifdef Q_OS_UNIX
- void setupChildProcess()
+ public:
+ QExternalProcess()
{
- // run in user code
- QProcess::setupChildProcess();
-
- if (processChannelMode() == ForwardedChannels) {
- // reopen /dev/tty into stdin
- int fd = ::open("/dev/tty", O_RDONLY);
- if (fd == -1)
- return;
- ::dup2(fd, 0);
- ::close(fd);
- }
+ setChildProcessModifier([this]() {
+ // run in user code
+ if (processChannelMode() == ForwardedChannels) {
+ // reopen /dev/tty into stdin
+ int fd = ::open("/dev/tty", O_RDONLY);
+ if (fd == -1)
+ return;
+ ::dup2(fd, 0);
+ ::close(fd);
+ }
+ });
}
-#endif
};
+# else
+ using QExternalProcess = QProcess;
+# endif
#endif // QT_CONFIG(process)
class QExternalTestPrivate