summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/io/qprocess
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/io/qprocess')
-rw-r--r--tests/auto/corelib/io/qprocess/BLACKLIST6
-rw-r--r--tests/auto/corelib/io/qprocess/CMakeLists.txt39
-rw-r--r--tests/auto/corelib/io/qprocess/crasher.h60
-rw-r--r--tests/auto/corelib/io/qprocess/fileWriterProcess/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp32
-rw-r--r--tests/auto/corelib/io/qprocess/qprocess.pri22
-rw-r--r--tests/auto/corelib/io/qprocess/qprocess.pro18
-rw-r--r--tests/auto/corelib/io/qprocess/test/CMakeLists.txt48
-rw-r--r--tests/auto/corelib/io/qprocess/test/test.pro22
-rwxr-xr-xtests/auto/corelib/io/qprocess/testBatFiles/simple.bat4
-rwxr-xr-xtests/auto/corelib/io/qprocess/testBatFiles/with space.bat4
-rw-r--r--tests/auto/corelib/io/qprocess/testDetached/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/io/qprocess/testDetached/main.cpp31
-rw-r--r--tests/auto/corelib/io/qprocess/testDetached/testDetached.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testExitCodes/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testExitCodes/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testForwarding/CMakeLists.txt14
-rw-r--r--tests/auto/corelib/io/qprocess/testForwarding/main.cpp31
-rw-r--r--tests/auto/corelib/io/qprocess/testForwarding/testForwarding.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testForwardingHelper/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp31
-rw-r--r--tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testGuiProcess/CMakeLists.txt15
-rw-r--r--tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessCrash/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp44
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEOF/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho2/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho3/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEchoGui/CMakeLists.txt15
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEchoGui/testProcessEchoGui.pro8
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEnvironment/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessHang/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessHang/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessHang/testProcessHang.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessNormal/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro6
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessOutput/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/CMakeLists.txt25
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro6
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro8
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro9
-rw-r--r--tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/CMakeLists.txt14
-rw-r--r--tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/testSetNamedPipeHandleState.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testSetWorkingDirectory/CMakeLists.txt12
-rw-r--r--tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro4
-rw-r--r--tests/auto/corelib/io/qprocess/testSoftExit/CMakeLists.txt23
-rw-r--r--tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro12
-rw-r--r--tests/auto/corelib/io/qprocess/testSpaceInName/CMakeLists.txt15
-rw-r--r--tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp29
-rw-r--r--tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro5
-rw-r--r--tests/auto/corelib/io/qprocess/testUnixProcessParameters/CMakeLists.txt13
-rw-r--r--tests/auto/corelib/io/qprocess/testUnixProcessParameters/main.cpp109
-rw-r--r--tests/auto/corelib/io/qprocess/tst_qprocess.cpp1246
81 files changed, 1517 insertions, 1205 deletions
diff --git a/tests/auto/corelib/io/qprocess/BLACKLIST b/tests/auto/corelib/io/qprocess/BLACKLIST
deleted file mode 100644
index 682bcbc60c..0000000000
--- a/tests/auto/corelib/io/qprocess/BLACKLIST
+++ /dev/null
@@ -1,6 +0,0 @@
-[lockupsInStartDetached]
-redhatenterpriselinuxworkstation-6.6
-# QTBUG-48455
-[fileWriterProcess]
-windows-10 msvc-2017
-
diff --git a/tests/auto/corelib/io/qprocess/CMakeLists.txt b/tests/auto/corelib/io/qprocess/CMakeLists.txt
new file mode 100644
index 0000000000..17dea9688f
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(qprocess LANGUAGES CXX)
+ find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
+endif()
+
+add_subdirectory(test)
+add_subdirectory(testProcessCrash)
+add_subdirectory(testProcessEcho)
+add_subdirectory(testProcessEcho2)
+add_subdirectory(testProcessEcho3)
+add_subdirectory(testProcessEnvironment)
+add_subdirectory(testProcessHang)
+add_subdirectory(testProcessNormal)
+add_subdirectory(testProcessOutput)
+add_subdirectory(testProcessDeadWhileReading)
+add_subdirectory(testProcessEOF)
+add_subdirectory(testExitCodes)
+add_subdirectory(testForwarding)
+add_subdirectory(testForwardingHelper)
+if(TARGET Qt::Widgets)
+ add_subdirectory(testGuiProcess)
+endif()
+add_subdirectory(testDetached)
+add_subdirectory(fileWriterProcess)
+add_subdirectory(testSetWorkingDirectory)
+add_subdirectory(testSoftExit)
+add_subdirectory(testProcessSpacesArgs)
+add_subdirectory(testSpaceInName)
+if(WIN32)
+ add_subdirectory(testProcessEchoGui)
+ add_subdirectory(testSetNamedPipeHandleState)
+endif()
+if(UNIX)
+ add_subdirectory(testUnixProcessParameters)
+endif()
diff --git a/tests/auto/corelib/io/qprocess/crasher.h b/tests/auto/corelib/io/qprocess/crasher.h
new file mode 100644
index 0000000000..f1ca82a86b
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/crasher.h
@@ -0,0 +1,60 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2020 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#if defined(_MSC_VER)
+# include <intrin.h>
+#endif
+#if __has_include(<signal.h>)
+# include <signal.h>
+#endif
+#if __has_include(<sys/resource.h>)
+# include <sys/resource.h>
+#endif
+
+#ifndef __has_builtin
+# define __has_builtin(x) 0
+#endif
+
+namespace tst_QProcessCrash {
+struct NoCoreDumps
+{
+#if defined(RLIMIT_CORE)
+ struct rlimit rlim;
+ NoCoreDumps()
+ {
+ if (getrlimit(RLIMIT_CORE, &rlim) == 0 && rlim.rlim_cur != 0) {
+ struct rlimit newrlim = rlim;
+ newrlim.rlim_cur = 0;
+ setrlimit(RLIMIT_CORE, &newrlim);
+ }
+ }
+ ~NoCoreDumps()
+ {
+ setrlimit(RLIMIT_CORE, &rlim);
+ }
+#endif // RLIMIT_CORE
+};
+
+void crashFallback(volatile int *ptr = nullptr)
+{
+ *ptr = 0;
+}
+
+void crash()
+{
+#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
+ __ud2();
+#elif defined(_MSC_VER) && defined(_M_ARM64)
+ __debugbreak();
+#elif __has_builtin(__builtin_trap)
+ __builtin_trap();
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+ asm("ud2");
+#elif defined(SIGILL)
+ raise(SIGILL);
+#endif
+
+ crashFallback();
+}
+} // namespace tst_QProcessCrash
diff --git a/tests/auto/corelib/io/qprocess/fileWriterProcess/CMakeLists.txt b/tests/auto/corelib/io/qprocess/fileWriterProcess/CMakeLists.txt
new file mode 100644
index 0000000000..d431ba2c3f
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/fileWriterProcess/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## fileWriterProcess Binary:
+#####################################################################
+
+qt_internal_add_executable(fileWriterProcess
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro b/tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro
deleted file mode 100644
index 2744491151..0000000000
--- a/tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG += cmdline
-QT = core
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp b/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp
index efeadadb93..0349a48067 100644
--- a/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp
+++ b/tests/auto/corelib/io/qprocess/fileWriterProcess/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QCoreApplication>
#include <QFile>
@@ -34,7 +9,8 @@ int main(int argc, char **argv)
{
QCoreApplication ca(argc, argv);
QFile f;
- f.open(stdin, QIODevice::ReadOnly);
+ if (!f.open(stdin, QIODevice::ReadOnly))
+ return 1;
QByteArray input;
char buf[1024];
qint64 len;
diff --git a/tests/auto/corelib/io/qprocess/qprocess.pri b/tests/auto/corelib/io/qprocess/qprocess.pri
deleted file mode 100644
index 8d17090545..0000000000
--- a/tests/auto/corelib/io/qprocess/qprocess.pri
+++ /dev/null
@@ -1,22 +0,0 @@
-SUBPROGRAMS = \
- testProcessCrash \
- testProcessEcho \
- testProcessEcho2 \
- testProcessEcho3 \
- testProcessEnvironment \
- testProcessHang \
- testProcessNormal \
- testProcessOutput \
- testProcessDeadWhileReading \
- testProcessEOF \
- testExitCodes \
- testForwarding \
- testForwardingHelper \
- testGuiProcess \
- testDetached \
- fileWriterProcess \
- testSetWorkingDirectory \
- testSoftExit
-
-!qtHaveModule(widgets): SUBPROGRAMS -= \
- testGuiProcess
diff --git a/tests/auto/corelib/io/qprocess/qprocess.pro b/tests/auto/corelib/io/qprocess/qprocess.pro
deleted file mode 100644
index 3867ac5741..0000000000
--- a/tests/auto/corelib/io/qprocess/qprocess.pro
+++ /dev/null
@@ -1,18 +0,0 @@
-TEMPLATE = subdirs
-
-include(qprocess.pri)
-SUBDIRS = $$SUBPROGRAMS
-# Add special cases
-SUBDIRS += testProcessSpacesArgs/nospace.pro \
- testProcessSpacesArgs/onespace.pro \
- testProcessSpacesArgs/twospaces.pro \
- testSpaceInName
-
-win32 {
- SUBDIRS += \
- testProcessEchoGui \
- testSetNamedPipeHandleState
-}
-
-test.depends += $$SUBDIRS
-SUBDIRS += test
diff --git a/tests/auto/corelib/io/qprocess/test/CMakeLists.txt b/tests/auto/corelib/io/qprocess/test/CMakeLists.txt
new file mode 100644
index 0000000000..89893583ac
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/test/CMakeLists.txt
@@ -0,0 +1,48 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qprocess Test:
+#####################################################################
+
+qt_internal_add_test(tst_qprocess
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../"
+ SOURCES
+ ../tst_qprocess.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::Network
+ Qt::TestPrivate
+)
+
+## Build assorted sub-programs called from the test:
+add_dependencies(tst_qprocess
+ testProcessCrash
+ testProcessEcho
+ testProcessEcho2
+ testProcessEcho3
+ testProcessEnvironment
+ testProcessHang
+ testProcessNormal
+ testProcessOutput
+ testProcessDeadWhileReading
+ testProcessEOF
+ testExitCodes
+ testForwarding
+ testDetached
+ fileWriterProcess
+ testSetWorkingDirectory
+ testSoftExit
+ nospace onespace twospaces
+ testSpaceInName
+)
+if(TARGET Qt::Widgets)
+ add_dependencies(tst_qprocess testGuiProcess)
+endif()
+if(WIN32)
+ add_dependencies(tst_qprocess testProcessEchoGui testSetNamedPipeHandleState)
+endif()
+
+if(UNIX)
+ add_dependencies(tst_qprocess testUnixProcessParameters)
+endif()
diff --git a/tests/auto/corelib/io/qprocess/test/test.pro b/tests/auto/corelib/io/qprocess/test/test.pro
deleted file mode 100644
index 63187c9668..0000000000
--- a/tests/auto/corelib/io/qprocess/test/test.pro
+++ /dev/null
@@ -1,22 +0,0 @@
-CONFIG += testcase
-CONFIG -= debug_and_release_target
-QT = core-private testlib network
-SOURCES = ../tst_qprocess.cpp
-INCLUDEPATH += ../../../../../shared
-HEADERS += ../../../../../shared/emulationdetector.h
-
-TARGET = ../tst_qprocess
-
-win32:TESTDATA += ../testBatFiles/*
-
-include(../qprocess.pri)
-
-mac:CONFIG += insignificant_test # QTBUG-25895 - sometimes hangs
-
-for(file, SUBPROGRAMS): TEST_HELPER_INSTALLS += "../$${file}/$${file}"
-
-TEST_HELPER_INSTALLS += \
- ../testProcessSpacesArgs/nospace \
- "../testProcessSpacesArgs/one space" \
- "../testProcessSpacesArgs/two space s" \
- "../test Space In Name/testSpaceInName"
diff --git a/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat b/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat
index 900f7ae356..8567e16850 100755
--- a/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat
+++ b/tests/auto/corelib/io/qprocess/testBatFiles/simple.bat
@@ -1,2 +1,4 @@
+:: Copyright (C) 2024 The Qt Company Ltd.
+:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
@echo off
-echo Hello \ No newline at end of file
+echo Hello
diff --git a/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat b/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat
index 900f7ae356..8567e16850 100755
--- a/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat
+++ b/tests/auto/corelib/io/qprocess/testBatFiles/with space.bat
@@ -1,2 +1,4 @@
+:: Copyright (C) 2024 The Qt Company Ltd.
+:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
@echo off
-echo Hello \ No newline at end of file
+echo Hello
diff --git a/tests/auto/corelib/io/qprocess/testDetached/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testDetached/CMakeLists.txt
new file mode 100644
index 0000000000..2439fc67a7
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testDetached/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testDetached Binary:
+#####################################################################
+
+qt_internal_add_executable(testDetached
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testDetached/main.cpp b/tests/auto/corelib/io/qprocess/testDetached/main.cpp
index c10e32d584..9b0b3855a0 100644
--- a/tests/auto/corelib/io/qprocess/testDetached/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testDetached/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QCoreApplication>
#include <QDebug>
#include <QStringList>
@@ -66,7 +41,7 @@ struct Args
static Args parseArguments(const QStringList &args)
{
Args result;
- if (args.count() < 2) {
+ if (args.size() < 2) {
result.exitCode = 128;
result.errorMessage = "Usage: testDetached [--out-channel={stdout|stderr}] filename.txt\n";
return result;
diff --git a/tests/auto/corelib/io/qprocess/testDetached/testDetached.pro b/tests/auto/corelib/io/qprocess/testDetached/testDetached.pro
deleted file mode 100644
index 3d80b668df..0000000000
--- a/tests/auto/corelib/io/qprocess/testDetached/testDetached.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-SOURCES = main.cpp
-QT = core
-CONFIG += cmdline
-INSTALLS =
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testExitCodes/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testExitCodes/CMakeLists.txt
new file mode 100644
index 0000000000..bc03f52d00
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testExitCodes/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testExitCodes Binary:
+#####################################################################
+
+qt_internal_add_executable(testExitCodes
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testExitCodes/main.cpp b/tests/auto/corelib/io/qprocess/testExitCodes/main.cpp
index f681870609..3f186d2272 100644
--- a/tests/auto/corelib/io/qprocess/testExitCodes/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testExitCodes/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdlib.h>
diff --git a/tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro b/tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro
deleted file mode 100644
index 5eaf8dc881..0000000000
--- a/tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-SOURCES += main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testForwarding/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testForwarding/CMakeLists.txt
new file mode 100644
index 0000000000..77739d2c68
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testForwarding/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testForwarding Binary:
+#####################################################################
+
+qt_internal_add_executable(testForwarding
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+)
+
+add_dependencies(testForwarding testForwardingHelper)
diff --git a/tests/auto/corelib/io/qprocess/testForwarding/main.cpp b/tests/auto/corelib/io/qprocess/testForwarding/main.cpp
index b5d56a1138..774a8622e1 100644
--- a/tests/auto/corelib/io/qprocess/testForwarding/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testForwarding/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtCore/QCoreApplication>
#include <QtCore/QDeadlineTimer>
@@ -38,7 +13,7 @@ static bool waitForDoneFileWritten(const QString &filePath, int msecs = 30000)
{
QDeadlineTimer t(msecs);
do {
- QThread::msleep(250);
+ QThread::sleep(std::chrono::milliseconds{250});
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly))
continue;
diff --git a/tests/auto/corelib/io/qprocess/testForwarding/testForwarding.pro b/tests/auto/corelib/io/qprocess/testForwarding/testForwarding.pro
deleted file mode 100644
index 4d91e0cf36..0000000000
--- a/tests/auto/corelib/io/qprocess/testForwarding/testForwarding.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG += cmdline
-DESTDIR = ./
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testForwardingHelper/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testForwardingHelper/CMakeLists.txt
new file mode 100644
index 0000000000..9f5f064307
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testForwardingHelper/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testForwardingHelper Binary:
+#####################################################################
+
+qt_internal_add_executable(testForwardingHelper
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp b/tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp
index 682ca7346b..4b4d9d4715 100644
--- a/tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testForwardingHelper/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <fstream>
#include <stdio.h>
@@ -36,8 +11,8 @@ int main(int argc, char *argv[])
return 1;
}
fputs("out data", stdout);
- fputs("err data", stderr);
fflush(stdout);
+ fputs("err data", stderr);
fflush(stderr);
std::ofstream out(argv[1]);
out << "That's all folks!";
diff --git a/tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro b/tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testGuiProcess/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testGuiProcess/CMakeLists.txt
new file mode 100644
index 0000000000..781f49e515
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testGuiProcess/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testGuiProcess Binary:
+#####################################################################
+
+qt_internal_add_executable(testGuiProcess
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+ LIBRARIES
+ Qt::Gui
+ Qt::Widgets
+)
diff --git a/tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp b/tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp
index 98babfacb8..1c65268511 100644
--- a/tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testGuiProcess/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro b/tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro
deleted file mode 100644
index ef438d6399..0000000000
--- a/tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES += main.cpp
-QT += widgets
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessCrash/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessCrash/CMakeLists.txt
new file mode 100644
index 0000000000..2f167899eb
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessCrash/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessCrash Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessCrash
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp b/tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp
index 262db73d72..a5f1eef88a 100644
--- a/tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessCrash/main.cpp
@@ -1,40 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2020 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-
-struct Foo
-{
- int i;
-};
+#include "../crasher.h"
+using namespace tst_QProcessCrash;
int main()
{
- *(volatile char*)0 = 0;
- Foo *f = 0;
- return f->i;
+ [[maybe_unused]] // NoCoreDumps may be an empty struct, not a RAII class
+ NoCoreDumps disableCoreDumps;
+ crash();
+ return 0;
}
diff --git a/tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro b/tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro
deleted file mode 100644
index 640ce4cd09..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-SOURCES = main.cpp
-CONFIG += cmdline
-CONFIG -= qt
-
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/CMakeLists.txt
new file mode 100644
index 0000000000..bdd82c6419
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessDeadWhileReading Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessDeadWhileReading
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp
index eb780fbc3a..0add9d56de 100644
--- a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro
deleted file mode 100644
index c7be60a82d..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessEOF/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessEOF/CMakeLists.txt
new file mode 100644
index 0000000000..8914bf181d
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEOF/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessEOF Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessEOF
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp
index 4fb2e29c2d..a0efdbd271 100644
--- a/tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessEOF/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro b/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessEcho/CMakeLists.txt
new file mode 100644
index 0000000000..071156f759
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessEcho Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessEcho
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp
index e18e48e516..7b87380900 100644
--- a/tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro b/tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho2/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessEcho2/CMakeLists.txt
new file mode 100644
index 0000000000..9f71b1ebb6
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho2/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessEcho2 Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessEcho2
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp
index ce4494b048..b67480e6bb 100644
--- a/tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho2/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro b/tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho3/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessEcho3/CMakeLists.txt
new file mode 100644
index 0000000000..badc9ef82d
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho3/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessEcho3 Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessEcho3
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp
index dfd6e009db..161f8bd547 100644
--- a/tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessEcho3/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro b/tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessEchoGui/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessEchoGui/CMakeLists.txt
new file mode 100644
index 0000000000..43663e62e8
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEchoGui/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessEchoGui Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessEchoGui
+ GUI
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main_win.cpp
+)
+target_link_libraries(testProcessEchoGui PRIVATE user32)
diff --git a/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp b/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp
index abe957c1ea..ab54e4a328 100644
--- a/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessEchoGui/main_win.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <windows.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessEchoGui/testProcessEchoGui.pro b/tests/auto/corelib/io/qprocess/testProcessEchoGui/testProcessEchoGui.pro
deleted file mode 100644
index e41ed0a425..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessEchoGui/testProcessEchoGui.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-win32 {
- SOURCES = main_win.cpp
- QMAKE_USE += user32
-}
-
-CONFIG -= qt app_bundle
-DESTDIR = ./
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/io/qprocess/testProcessEnvironment/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessEnvironment/CMakeLists.txt
new file mode 100644
index 0000000000..9069bbc7c8
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessEnvironment/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessEnvironment Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessEnvironment
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp b/tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp
index 9f13f5c00f..dae98c3af6 100644
--- a/tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessEnvironment/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
#include <stdlib.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro b/tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessHang/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessHang/CMakeLists.txt
new file mode 100644
index 0000000000..cb6f490c40
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessHang/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessHang Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessHang
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessHang/main.cpp b/tests/auto/corelib/io/qprocess/testProcessHang/main.cpp
index cb904134f9..89fcadfb8f 100644
--- a/tests/auto/corelib/io/qprocess/testProcessHang/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessHang/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessHang/testProcessHang.pro b/tests/auto/corelib/io/qprocess/testProcessHang/testProcessHang.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessHang/testProcessHang.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testProcessNormal/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessNormal/CMakeLists.txt
new file mode 100644
index 0000000000..7eb6388792
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessNormal/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessNormal Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessNormal
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp b/tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp
index 4611ed4547..a714713cf2 100644
--- a/tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessNormal/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
int main()
diff --git a/tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro b/tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro
deleted file mode 100644
index 7e1119c117..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-SOURCES = main.cpp
-CONFIG += cmdline
-CONFIG -= qt
-
-DESTDIR = ./
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testProcessOutput/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessOutput/CMakeLists.txt
new file mode 100644
index 0000000000..78005b2b93
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessOutput/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessOutput Binary:
+#####################################################################
+
+qt_internal_add_executable(testProcessOutput
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp b/tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp
index 4934708153..08d059e0f9 100644
--- a/tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessOutput/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro b/tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro
deleted file mode 100644
index 0bbb6b3c0e..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/CMakeLists.txt
new file mode 100644
index 0000000000..5ea7bf53f4
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+qt_internal_add_executable(nospace
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
+
+qt_internal_add_executable(onespace
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
+set_target_properties(onespace PROPERTIES OUTPUT_NAME "one space")
+
+qt_internal_add_executable(twospaces
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
+set_target_properties(twospaces PROPERTIES OUTPUT_NAME "two space s")
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp
index 0d40a9b83c..2c319fa9af 100644
--- a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro
deleted file mode 100644
index 7954a2f74b..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro
+++ /dev/null
@@ -1,6 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
-OBJECTS_DIR = $${OBJECTS_DIR}-nospace
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro
deleted file mode 100644
index 44a365c9a5..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
-OBJECTS_DIR = $${OBJECTS_DIR}-onespace
-
-TARGET = "one space"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro
deleted file mode 100644
index bd2db9fb6d..0000000000
--- a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
-OBJECTS_DIR = $${OBJECTS_DIR}-twospaces
-
-TARGET = "two space s"
-DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/CMakeLists.txt
new file mode 100644
index 0000000000..5e532aa017
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testSetNamedPipeHandleState Binary:
+#####################################################################
+
+qt_internal_add_executable(testSetNamedPipeHandleState
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
+target_link_libraries(testSetNamedPipeHandleState PRIVATE kernel32.lib)
diff --git a/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/main.cpp b/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/main.cpp
index 488b03ab57..ace55e9058 100644
--- a/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <windows.h>
diff --git a/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/testSetNamedPipeHandleState.pro b/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/testSetNamedPipeHandleState.pro
deleted file mode 100644
index 6a23e52d95..0000000000
--- a/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/testSetNamedPipeHandleState.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
diff --git a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/CMakeLists.txt
new file mode 100644
index 0000000000..f5b9c22c90
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testSetWorkingDirectory Binary:
+#####################################################################
+
+qt_internal_add_executable(testSetWorkingDirectory
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp
index 37d7deb1ac..c12ca2de7a 100644
--- a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QCoreApplication>
diff --git a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro
deleted file mode 100644
index 4d91e0cf36..0000000000
--- a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = main.cpp
-CONFIG += cmdline
-DESTDIR = ./
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testSoftExit/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testSoftExit/CMakeLists.txt
new file mode 100644
index 0000000000..44099dcab1
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSoftExit/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testSoftExit Binary:
+#####################################################################
+
+qt_internal_add_executable(testSoftExit
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+)
+
+qt_internal_extend_target(testSoftExit CONDITION WIN32
+ SOURCES
+ main_win.cpp
+ LIBRARIES
+ user32
+)
+
+qt_internal_extend_target(testSoftExit CONDITION UNIX
+ SOURCES
+ main_unix.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp b/tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp
index ed0f16ac17..6d5078e75e 100644
--- a/tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp
+++ b/tests/auto/corelib/io/qprocess/testSoftExit/main_unix.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <sys/types.h>
diff --git a/tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp b/tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp
index 898029483f..cbef8418e6 100644
--- a/tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp
+++ b/tests/auto/corelib/io/qprocess/testSoftExit/main_win.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <windows.h>
diff --git a/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro b/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro
deleted file mode 100644
index 964c47f6ae..0000000000
--- a/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro
+++ /dev/null
@@ -1,12 +0,0 @@
-win32 {
- SOURCES = main_win.cpp
- QMAKE_USE += user32
-}
-unix {
- SOURCES = main_unix.cpp
-}
-
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = ./
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testSpaceInName/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testSpaceInName/CMakeLists.txt
new file mode 100644
index 0000000000..9cc05bfc3d
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testSpaceInName/CMakeLists.txt
@@ -0,0 +1,15 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testSpaceInName Binary:
+#####################################################################
+
+qt_internal_add_executable(testSpaceInName
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
+set_property(TARGET testSpaceInName PROPERTY
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../test Space In Name")
diff --git a/tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp b/tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp
index 0e2374de06..ca54a6bfde 100644
--- a/tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp
+++ b/tests/auto/corelib/io/qprocess/testSpaceInName/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <stdio.h>
diff --git a/tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro b/tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro
deleted file mode 100644
index 48f28c4c8b..0000000000
--- a/tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-SOURCES = main.cpp
-CONFIG -= qt
-CONFIG += cmdline
-DESTDIR = "../test Space In Name"
-QT = core
diff --git a/tests/auto/corelib/io/qprocess/testUnixProcessParameters/CMakeLists.txt b/tests/auto/corelib/io/qprocess/testUnixProcessParameters/CMakeLists.txt
new file mode 100644
index 0000000000..9b6c48933c
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testUnixProcessParameters/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2023 Intel Corporation.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## testProcessNormal Binary:
+#####################################################################
+
+qt_internal_add_executable(testUnixProcessParameters
+ OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/"
+ CORE_LIBRARY None
+ SOURCES
+ main.cpp
+)
diff --git a/tests/auto/corelib/io/qprocess/testUnixProcessParameters/main.cpp b/tests/auto/corelib/io/qprocess/testUnixProcessParameters/main.cpp
new file mode 100644
index 0000000000..42a173debe
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess/testUnixProcessParameters/main.cpp
@@ -0,0 +1,109 @@
+// Copyright (C) 2023 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <string_view>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sched.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+int main(int argc, char **argv)
+{
+ if (argc < 2) {
+ printf("Usage: %s command [extra]\nSee source code for commands\n",
+ argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ std::string_view cmd = argv[1];
+ errno = 0;
+
+ if (cmd.size() == 0) {
+ // just checking that we did get here
+ return EXIT_SUCCESS;
+ }
+
+ if (cmd == "reset-ids") {
+ if (getuid() == geteuid() && getgid() == getegid())
+ return EXIT_SUCCESS;
+ fprintf(stderr, "Real: %d %d; Effective: %d %d\n",
+ getuid(), getgid(), geteuid(), getegid());
+ return EXIT_FAILURE;
+ }
+
+ if (cmd == "reset-sighand") {
+ bool ok = true;
+
+ // confirm our signal block mask is empty
+ sigset_t set;
+ sigprocmask(SIG_SETMASK, nullptr, &set);
+ for (int signo = 1; signo < NSIG; ++signo) {
+ if (sigismember(&set, signo)) {
+ fprintf(stderr, "'%s' is blocked.\n", strsignal(signo));
+ ok = false;
+ }
+ }
+
+ // confirm SIGUSR1 was not ignored
+ struct sigaction action;
+ sigaction(SIGUSR1, nullptr, &action);
+ if (action.sa_handler != SIG_DFL) {
+ fprintf(stderr, "SIGUSR1 is SIG_IGN\n");
+ ok = false;
+ }
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+
+ if (cmd == "ignore-sigpipe") {
+ // confirm SIGPIPE was ignored
+ struct sigaction action;
+ sigaction(SIGPIPE, nullptr, &action);
+ if (action.sa_handler == SIG_IGN)
+ return EXIT_SUCCESS;
+ fprintf(stderr, "SIGPIPE is SIG_DFL\n");
+ return EXIT_FAILURE;
+ }
+
+ if (cmd == "file-descriptors") {
+ int fd = atoi(argv[2]);
+ if (close(fd) < 0 && errno == EBADF)
+ return EXIT_SUCCESS;
+ fprintf(stderr, "%d is a valid file descriptor\n", fd);
+ return EXIT_FAILURE;
+ }
+
+ if (cmd == "file-descriptors2") {
+ int fd1 = atoi(argv[2]); // should be open
+ int fd2 = atoi(argv[3]); // should be closed
+ if (close(fd1) < 0)
+ fprintf(stderr, "%d was not a valid file descriptor\n", fd1);
+ if (close(fd2) == 0 || errno != EBADF)
+ fprintf(stderr, "%d is a valid file descriptor\n", fd2);
+ return EXIT_SUCCESS;
+ }
+
+ if (cmd == "noctty") {
+ int fd = open("/dev/tty", O_RDONLY);
+ if (fd == -1)
+ return EXIT_SUCCESS;
+ fprintf(stderr, "Could open /dev/tty\n");
+ return EXIT_FAILURE;
+ }
+
+ if (cmd == "setsid") {
+ pid_t pgid = getpgrp();
+ if (pgid == getpid())
+ return EXIT_SUCCESS;
+ fprintf(stderr, "Process group was %d\n", pgid);
+ return EXIT_FAILURE;
+ }
+
+ fprintf(stderr, "Unknown command \"%s\"", cmd.data());
+ return EXIT_FAILURE;
+}
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
index e799369c8a..5f35732979 100644
--- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
@@ -1,49 +1,37 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2016 Intel Corporation.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <emulationdetector.h>
-
-#include <QtTest/QtTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2022 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include <QTest>
+#include <QTestEventLoop>
+#include <QSignalSpy>
+
#include <QtCore/QProcess>
#include <QtCore/QDir>
#include <QtCore/QElapsedTimer>
#include <QtCore/QFile>
#include <QtCore/QThread>
#include <QtCore/QTemporaryDir>
-#include <QtCore/QRegExp>
+#include <QtCore/QRegularExpression>
#include <QtCore/QDebug>
#include <QtCore/QMetaType>
+#include <QtCore/QScopeGuard>
#include <QtNetwork/QHostInfo>
+
+#include <qplatformdefs.h>
+#ifdef Q_OS_UNIX
+# include <private/qcore_unix_p.h>
+# include <sys/wait.h>
+#endif
+
+#include <QtTest/private/qemulationdetector_p.h>
+
#include <stdlib.h>
-typedef void (QProcess::*QProcessFinishedSignal1)(int);
-typedef void (QProcess::*QProcessFinishedSignal2)(int, QProcess::ExitStatus);
+#include "crasher.h"
+
+using namespace Qt::StringLiterals;
+
typedef void (QProcess::*QProcessErrorSignal)(QProcess::ProcessError);
class tst_QProcess : public QObject
@@ -59,6 +47,8 @@ private slots:
void getSetCheck();
void constructing();
void simpleStart();
+ void startCommand();
+ void startCommandEmptyString();
void startWithOpen();
void startWithOldOpen();
void execute();
@@ -99,8 +89,11 @@ private slots:
void environmentIsSorted();
void spaceInName();
void setStandardInputFile();
+ void setStandardInputFileFailure();
void setStandardOutputFile_data();
void setStandardOutputFile();
+ void setStandardOutputFileFailure_data() { setStandardOutputFile_data(); }
+ void setStandardOutputFileFailure();
void setStandardOutputFileNullDevice();
void setStandardOutputFileAndWaitForBytesWritten();
void setStandardOutputProcess_data();
@@ -111,6 +104,7 @@ private slots:
void discardUnwantedOutput();
void setWorkingDirectory();
void setNonExistentWorkingDirectory();
+ void detachedSetNonExistentWorkingDirectory();
void exitStatus_data();
void exitStatus();
@@ -125,6 +119,22 @@ private slots:
void nativeArguments();
void createProcessArgumentsModifier();
#endif // Q_OS_WIN
+#if defined(Q_OS_UNIX)
+ void setChildProcessModifier_data();
+ void setChildProcessModifier();
+ void failChildProcessModifier_data() { setChildProcessModifier_data(); }
+ void failChildProcessModifier();
+ void throwInChildProcessModifier();
+ void terminateInChildProcessModifier_data();
+ void terminateInChildProcessModifier();
+ void raiseInChildProcessModifier();
+ void unixProcessParameters_data();
+ void unixProcessParameters();
+ void impossibleUnixProcessParameters_data();
+ void impossibleUnixProcessParameters();
+ void unixProcessParametersAndChildModifier();
+ void unixProcessParametersOtherFileDescriptors();
+#endif
void exitCodeTest();
void systemEnvironment();
void lockupsInStartDetached();
@@ -142,6 +152,8 @@ private slots:
void startStopStartStopBuffers();
void processEventsInAReadyReadSlot_data();
void processEventsInAReadyReadSlot();
+ void startFromCurrentWorkingDir_data();
+ void startFromCurrentWorkingDir();
// keep these at the end, since they use lots of processes and sometimes
// caused obscure failures to occur in tests that followed them (esp. on the Mac)
@@ -151,13 +163,6 @@ private slots:
void failToStartEmptyArgs_data();
void failToStartEmptyArgs();
-#if QT_DEPRECATED_SINCE(5, 13)
- void crashTest2_deprecated();
- void restartProcessDeadlock_deprecated();
- void waitForReadyReadInAReadyReadSlot_deprecated();
- void finishProcessBeforeReadingDone_deprecated();
-#endif
-
protected slots:
void readFromProcess();
void exitLoopSlot();
@@ -167,16 +172,28 @@ protected slots:
void waitForBytesWrittenInABytesWrittenSlotSlot();
private:
+ QString nonExistentFileName = u"/this/file/cant/exist/hopefully"_s;
+
qint64 bytesAvailable;
QTemporaryDir m_temporaryDir;
+ bool haveWorkingVFork = false;
};
void tst_QProcess::initTestCase()
{
+#if defined(QT_ASAN_ENABLED)
+ QSKIP("Skipping QProcess tests under ASAN as they are flaky (QTBUG-109329)");
+#endif
QVERIFY2(m_temporaryDir.isValid(), qPrintable(m_temporaryDir.errorString()));
// 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()
@@ -194,14 +211,6 @@ void tst_QProcess::getSetCheck()
QProcess obj1;
// ProcessChannelMode QProcess::readChannelMode()
// void QProcess::setProcessChannelMode(ProcessChannelMode)
-#if QT_DEPRECATED_SINCE(5, 13)
- obj1.setProcessChannelMode(QProcess::ProcessChannelMode(QProcess::SeparateChannels));
- QCOMPARE(QProcess::ProcessChannelMode(QProcess::SeparateChannels), obj1.readChannelMode());
- obj1.setProcessChannelMode(QProcess::ProcessChannelMode(QProcess::MergedChannels));
- QCOMPARE(QProcess::ProcessChannelMode(QProcess::MergedChannels), obj1.readChannelMode());
- obj1.setProcessChannelMode(QProcess::ProcessChannelMode(QProcess::ForwardedChannels));
- QCOMPARE(QProcess::ProcessChannelMode(QProcess::ForwardedChannels), obj1.readChannelMode());
-#endif
obj1.setProcessChannelMode(QProcess::ProcessChannelMode(QProcess::SeparateChannels));
QCOMPARE(QProcess::ProcessChannelMode(QProcess::SeparateChannels), obj1.processChannelMode());
obj1.setProcessChannelMode(QProcess::ProcessChannelMode(QProcess::MergedChannels));
@@ -225,7 +234,7 @@ void tst_QProcess::constructing()
QCOMPARE(process.environment(), QStringList());
QCOMPARE(process.error(), QProcess::UnknownError);
QCOMPARE(process.state(), QProcess::NotRunning);
- QCOMPARE(process.pid(), Q_PID(0));
+ QCOMPARE(process.processId(), 0);
QCOMPARE(process.readAllStandardOutput(), QByteArray());
QCOMPARE(process.readAllStandardError(), QByteArray());
QCOMPARE(process.canReadLine(), false);
@@ -271,12 +280,45 @@ void tst_QProcess::simpleStart()
process.reset();
- QCOMPARE(spy.count(), 3);
+ QCOMPARE(spy.size(), 3);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(spy.at(0).at(0)), QProcess::Starting);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(spy.at(1).at(0)), QProcess::Running);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(spy.at(2).at(0)), QProcess::NotRunning);
}
+void tst_QProcess::startCommand()
+{
+ QProcess process;
+ process.startCommand("testProcessSpacesArgs/nospace foo \"b a r\" baz");
+ QVERIFY2(process.waitForStarted(), qPrintable(process.errorString()));
+ QVERIFY2(process.waitForFinished(), qPrintable(process.errorString()));
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+ QCOMPARE(process.exitCode(), 0);
+ QByteArray actual = process.readAll();
+ actual.remove(0, actual.indexOf('|') + 1);
+ QByteArray expected = "foo|b a r|baz";
+ QCOMPARE(actual, expected);
+}
+
+void tst_QProcess::startCommandEmptyString()
+{
+ static const char warningMsg[] =
+ "QProcess::startCommand: empty or whitespace-only command was provided";
+ QProcess process;
+
+ QTest::ignoreMessage(QtWarningMsg, warningMsg);
+ process.startCommand("");
+ QVERIFY(!process.waitForStarted());
+
+ QTest::ignoreMessage(QtWarningMsg, warningMsg);
+ process.startCommand(" ");
+ QVERIFY(!process.waitForStarted());
+
+ QTest::ignoreMessage(QtWarningMsg, warningMsg);
+ process.startCommand("\t\n");
+ QVERIFY(!process.waitForStarted());
+}
+
void tst_QProcess::startWithOpen()
{
QProcess p;
@@ -330,9 +372,7 @@ void tst_QProcess::readFromProcess()
{
QProcess *process = qobject_cast<QProcess *>(sender());
QVERIFY(process);
- int lines = 0;
while (process->canReadLine()) {
- ++lines;
process->readLine();
}
}
@@ -350,34 +390,24 @@ void tst_QProcess::crashTest()
qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
QSignalSpy spy(process.data(), &QProcess::errorOccurred);
- QSignalSpy spy2(process.data(), static_cast<QProcessFinishedSignal2>(&QProcess::finished));
+ QSignalSpy spy2(process.data(), &QProcess::finished);
QVERIFY(spy.isValid());
QVERIFY(spy2.isValid());
-#if QT_DEPRECATED_SINCE(5, 6)
- QSignalSpy spy3(process.data(), static_cast<QProcessErrorSignal>(&QProcess::error));
- QVERIFY(spy3.isValid());
-#endif
-
QVERIFY(process->waitForFinished(30000));
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
- QCOMPARE(spy2.count(), 1);
+ QCOMPARE(spy2.size(), 1);
QCOMPARE(*static_cast<const QProcess::ExitStatus *>(spy2.at(0).at(1).constData()), QProcess::CrashExit);
-#if QT_DEPRECATED_SINCE(5, 6)
- QCOMPARE(spy3.count(), 1);
- QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy3.at(0).at(0).constData()), QProcess::Crashed);
-#endif
-
QCOMPARE(process->exitStatus(), QProcess::CrashExit);
// delete process;
process.reset();
- QCOMPARE(stateSpy.count(), 3);
+ QCOMPARE(stateSpy.size(), 3);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(stateSpy.at(0).at(0)), QProcess::Starting);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(stateSpy.at(1).at(0)), QProcess::Running);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(stateSpy.at(2).at(0)), QProcess::NotRunning);
@@ -393,22 +423,21 @@ void tst_QProcess::crashTest2()
qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
QSignalSpy spy(&process, static_cast<QProcessErrorSignal>(&QProcess::errorOccurred));
- QSignalSpy spy2(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished));
+ QSignalSpy spy2(&process, &QProcess::finished);
QVERIFY(spy.isValid());
QVERIFY(spy2.isValid());
- QObject::connect(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished),
- this, &tst_QProcess::exitLoopSlot);
+ QObject::connect(&process, &QProcess::finished, this, &tst_QProcess::exitLoopSlot);
QTestEventLoop::instance().enterLoop(30);
if (QTestEventLoop::instance().timeout())
QFAIL("Failed to detect crash : operation timed out");
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
- QCOMPARE(spy2.count(), 1);
+ QCOMPARE(spy2.size(), 1);
QCOMPARE(*static_cast<const QProcess::ExitStatus *>(spy2.at(0).at(1).constData()), QProcess::CrashExit);
QCOMPARE(process.exitStatus(), QProcess::CrashExit);
@@ -514,9 +543,9 @@ void tst_QProcess::echoTest2()
break;
}
- QVERIFY(spy0.count() > 0);
- QVERIFY(spy1.count() > 0);
- QVERIFY(spy2.count() > 0);
+ QVERIFY(spy0.size() > 0);
+ QVERIFY(spy1.size() > 0);
+ QVERIFY(spy2.size() > 0);
QCOMPARE(process.readAllStandardOutput(), QByteArray("Hello"));
QCOMPARE(process.readAllStandardError(), QByteArray("Hello"));
@@ -617,8 +646,8 @@ void tst_QProcess::exitStatus()
QFETCH(QStringList, processList);
QFETCH(QList<QProcess::ExitStatus>, exitStatus);
- QCOMPARE(exitStatus.count(), processList.count());
- for (int i = 0; i < processList.count(); ++i) {
+ QCOMPARE(exitStatus.size(), processList.size());
+ for (int i = 0; i < processList.size(); ++i) {
process.start(processList.at(i));
QVERIFY(process.waitForStarted(5000));
QVERIFY(process.waitForFinished(30000));
@@ -665,22 +694,14 @@ void tst_QProcess::readTimeoutAndThenCrash()
qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
QSignalSpy spy(&process, &QProcess::errorOccurred);
QVERIFY(spy.isValid());
-#if QT_DEPRECATED_SINCE(5, 6)
- QSignalSpy spy2(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
- QVERIFY(spy2.isValid());
-#endif
process.kill();
QVERIFY(process.waitForFinished(5000));
QCOMPARE(process.state(), QProcess::NotRunning);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
-#if QT_DEPRECATED_SINCE(5, 6)
- QCOMPARE(spy2.count(), 1);
- QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy2.at(0).at(0).constData()), QProcess::Crashed);
-#endif
}
void tst_QProcess::waitForFinished()
@@ -724,15 +745,14 @@ void tst_QProcess::restartProcessDeadlock()
// process in the finished() connected slot causes a deadlock
// because of the way QProcessManager uses its locks.
QProcess process;
- connect(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished),
- this, &tst_QProcess::restartProcess);
+ connect(&process, &QProcess::finished, this, &tst_QProcess::restartProcess);
process.start("testProcessEcho/testProcessEcho");
QCOMPARE(process.write("", 1), qlonglong(1));
QVERIFY(process.waitForFinished(5000));
- QObject::disconnect(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished), nullptr, nullptr);
+ QObject::disconnect(&process, &QProcess::finished, nullptr, nullptr);
QCOMPARE(process.write("", 1), qlonglong(1));
QVERIFY(process.waitForFinished(5000));
@@ -857,7 +877,7 @@ void tst_QProcess::emitReadyReadOnlyWhenNewDataArrives()
proc.start("testProcessEcho/testProcessEcho");
- QCOMPARE(spy.count(), 0);
+ QCOMPARE(spy.size(), 0);
proc.write("A");
@@ -865,7 +885,7 @@ void tst_QProcess::emitReadyReadOnlyWhenNewDataArrives()
if (QTestEventLoop::instance().timeout())
QFAIL("Operation timed out");
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QTestEventLoop::instance().enterLoop(1);
QVERIFY(QTestEventLoop::instance().timeout());
@@ -931,8 +951,7 @@ public:
SoftExitProcess(int n) : waitedForFinished(false), n(n), killing(false)
{
- connect(this, static_cast<QProcessFinishedSignal2>(&QProcess::finished),
- this, &SoftExitProcess::finishedSlot);
+ connect(this, &QProcess::finished, this, &SoftExitProcess::finishedSlot);
switch (n) {
case 0:
@@ -1055,6 +1074,16 @@ void tst_QProcess::mergedChannels()
QVERIFY(process.waitForStarted(5000));
+ {
+ QCOMPARE(process.write("abc"), qlonglong(3));
+ while (process.bytesAvailable() < 6)
+ QVERIFY(process.waitForReadyRead(5000));
+ QCOMPARE(process.readAllStandardOutput(), QByteArray("aabbcc"));
+ QTest::ignoreMessage(QtWarningMsg,
+ "QProcess::readAllStandardError: Called with MergedChannels");
+ QCOMPARE(process.readAllStandardError(), QByteArray());
+ }
+
for (int i = 0; i < 100; ++i) {
QCOMPARE(process.write("abc"), qlonglong(3));
while (process.bytesAvailable() < 6)
@@ -1100,6 +1129,10 @@ void tst_QProcess::forwardedChannels_data()
<< true
<< int(QProcess::SeparateChannels) << int(QProcess::ManagedInputChannel)
<< QByteArray("out data") << QByteArray("err data");
+ QTest::newRow("detached-merged-forwarding")
+ << true
+ << int(QProcess::MergedChannels) << int(QProcess::ManagedInputChannel)
+ << QByteArray("out data" "err data") << QByteArray();
}
void tst_QProcess::forwardedChannels()
@@ -1117,9 +1150,8 @@ void tst_QProcess::forwardedChannels()
QVERIFY(process.waitForStarted(5000));
QCOMPARE(process.write("input"), 5);
process.closeWriteChannel();
- QVERIFY(process.waitForFinished(5000));
+ QVERIFY(process.waitForFinished(40000)); // testForwarding has a 30s wait
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
- QCOMPARE(process.exitCode(), 0);
const char *err;
switch (process.exitCode()) {
case 0: err = "ok"; break;
@@ -1172,13 +1204,12 @@ public:
}
protected:
- inline void run()
+ inline void run() override
{
exitCode = 90210;
QProcess process;
- connect(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished),
- this, &TestThread::catchExitCode, Qt::DirectConnection);
+ connect(&process, &QProcess::finished, this, &TestThread::catchExitCode, Qt::DirectConnection);
process.start("testProcessEcho/testProcessEcho");
@@ -1209,8 +1240,13 @@ void tst_QProcess::processInAThread()
void tst_QProcess::processesInMultipleThreads()
{
- if (EmulationDetector::isRunningArmOnX86())
- QSKIP("Flakily hangs in QEMU. QTBUG-67760");
+ if (QTestPrivate::isRunningArmOnX86())
+ QSKIP("Test is too slow to run on emulator");
+
+#if defined(Q_OS_QNX)
+ QSKIP("QNX: Large amount of threads is unstable and do not finish in given time");
+#endif
+
for (int i = 0; i < 10; ++i) {
// run from 1 to 10 threads, but run at least some tests
// with more threads than the ideal
@@ -1218,18 +1254,16 @@ void tst_QProcess::processesInMultipleThreads()
if (i > 7)
threadCount = qMax(threadCount, QThread::idealThreadCount() + 2);
- QVector<TestThread *> threads(threadCount);
+ QList<TestThread *> threads(threadCount);
+ QScopeGuard cleanup([&threads]() { qDeleteAll(threads); });
for (int j = 0; j < threadCount; ++j)
threads[j] = new TestThread;
for (int j = 0; j < threadCount; ++j)
threads[j]->start();
- for (int j = 0; j < threadCount; ++j) {
+ for (int j = 0; j < threadCount; ++j)
QVERIFY(threads[j]->wait(10000));
- }
- for (int j = 0; j < threadCount; ++j) {
+ for (int j = 0; j < threadCount; ++j)
QCOMPARE(threads[j]->code(), 0);
- }
- qDeleteAll(threads);
}
}
@@ -1251,8 +1285,7 @@ void tst_QProcess::waitForReadyReadInAReadyReadSlot()
{
QProcess process;
connect(&process, &QIODevice::readyRead, this, &tst_QProcess::waitForReadyReadInAReadyReadSlotSlot);
- connect(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished),
- this, &tst_QProcess::exitLoopSlot);
+ connect(&process, &QProcess::finished, this, &tst_QProcess::exitLoopSlot);
bytesAvailable = 0;
process.start("testProcessEcho/testProcessEcho");
@@ -1264,13 +1297,13 @@ void tst_QProcess::waitForReadyReadInAReadyReadSlot()
QTestEventLoop::instance().enterLoop(30);
QVERIFY(!QTestEventLoop::instance().timeout());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
process.disconnect();
QVERIFY(process.waitForFinished(5000));
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
QCOMPARE(process.exitCode(), 0);
- QVERIFY(process.bytesAvailable() > bytesAvailable);
+ QVERIFY(process.bytesAvailable() >= bytesAvailable);
}
void tst_QProcess::waitForReadyReadInAReadyReadSlotSlot()
@@ -1280,6 +1313,8 @@ void tst_QProcess::waitForReadyReadInAReadyReadSlotSlot()
bytesAvailable = process->bytesAvailable();
process->write("bar", 4);
QVERIFY(process->waitForReadyRead(5000));
+ QVERIFY(process->bytesAvailable() > bytesAvailable);
+ bytesAvailable = process->bytesAvailable();
QTestEventLoop::instance().exitLoop();
}
@@ -1298,7 +1333,7 @@ void tst_QProcess::waitForBytesWrittenInABytesWrittenSlot()
QTestEventLoop::instance().enterLoop(30);
QVERIFY(!QTestEventLoop::instance().timeout());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
process.write("", 1);
process.disconnect();
QVERIFY(process.waitForFinished());
@@ -1372,6 +1407,9 @@ void tst_QProcess::spaceArgsTest()
QFETCH(QStringList, args);
QFETCH(QString, stringArgs);
+ auto splitString = QProcess::splitCommand(stringArgs);
+ QCOMPARE(args, splitString);
+
QStringList programs;
programs << QString::fromLatin1("testProcessSpacesArgs/nospace")
<< QString::fromLatin1("testProcessSpacesArgs/one space")
@@ -1398,28 +1436,6 @@ void tst_QProcess::spaceArgsTest()
actual.removeFirst();
QCOMPARE(actual, args);
-
- if (program.contains(QLatin1Char(' ')))
- program = QLatin1Char('"') + program + QLatin1Char('"');
-
- if (!stringArgs.isEmpty())
- program += QLatin1Char(' ') + stringArgs;
-
- errorMessage.clear();
- process.start(program);
- started = process.waitForStarted(5000);
- if (!started)
- errorMessage = startFailMessage(program, process);
-
- QVERIFY2(started, errorMessage.constData());
- QVERIFY(process.waitForFinished(5000));
-
- actual = QString::fromLatin1(process.readAll()).split("|");
- QVERIFY(!actual.isEmpty());
- // not interested in the program name, it might be different.
- actual.removeFirst();
-
- QCOMPARE(actual, args);
}
}
@@ -1470,11 +1486,484 @@ void tst_QProcess::createProcessArgumentsModifier()
}
#endif // Q_OS_WIN
+#ifdef Q_OS_UNIX
+static constexpr int sigs[] = { SIGABRT, SIGILL, SIGSEGV };
+struct DisableCrashLogger
+{
+ // disable core dumps too
+ tst_QProcessCrash::NoCoreDumps disableCoreDumps {};
+ std::array<struct sigaction, std::size(sigs)> oldhandlers;
+ DisableCrashLogger()
+ {
+ struct sigaction def = {};
+ def.sa_handler = SIG_DFL;
+ for (uint i = 0; i < std::size(sigs); ++i)
+ sigaction(sigs[i], &def, &oldhandlers[i]);
+ }
+ ~DisableCrashLogger()
+ {
+ // restore them
+ for (uint i = 0; i < std::size(sigs); ++i)
+ sigaction(sigs[i], &oldhandlers[i], nullptr);
+ }
+};
+
+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)
+{
+ QT_WRITE(fd, messageFromChildProcess, strlen(messageFromChildProcess));
+ QT_CLOSE(fd);
+}
+
+void tst_QProcess::setChildProcessModifier_data()
+{
+ QTest::addColumn<bool>("detached");
+ 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]);
+ });
+ process.setProgram("testProcessNormal/testProcessNormal");
+ if (detached) {
+ process.startDetached();
+ } else {
+ process.start("testProcessNormal/testProcessNormal");
+ if (process.state() != QProcess::Starting)
+ QCOMPARE(process.state(), QProcess::Running);
+ QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString()));
+ QVERIFY2(process.waitForFinished(5000), qPrintable(process.errorString()));
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+ QCOMPARE(process.exitCode(), 0);
+ }
+
+ char buf[sizeof messageFromChildProcess] = {};
+ qt_safe_close(pipes[1]);
+ QCOMPARE(qt_safe_read(pipes[0], buf, sizeof(buf)), qint64(sizeof(messageFromChildProcess)) - 1);
+ QCOMPARE(buf, messageFromChildProcess);
+ qt_safe_close(pipes[0]);
+}
+
+void tst_QProcess::failChildProcessModifier()
+{
+ static const char failureMsg[] =
+ "Some error message from the child process would go here if this were a "
+ "real application";
+ static_assert(sizeof(failureMsg) < _POSIX_PIPE_BUF / 2,
+ "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);
+ });
+ process.setProgram("testProcessNormal/testProcessNormal");
+
+ if (detached) {
+ qint64 pid;
+ QVERIFY(!process.startDetached(&pid));
+ QCOMPARE(pid, -1);
+ } else {
+ process.start();
+ QVERIFY(!process.waitForStarted(5000));
+ }
+
+ QString errMsg = process.errorString();
+ QVERIFY2(errMsg.startsWith("Child process modifier reported error: "_L1 + failureMsg),
+ qPrintable(errMsg));
+ QVERIFY2(errMsg.endsWith(strerror(EPERM)), qPrintable(errMsg));
+}
+
+void tst_QProcess::throwInChildProcessModifier()
+{
+#ifndef __cpp_exceptions
+ Q_SKIP("Exceptions disabled.");
+#else
+ static constexpr char What[] = "tst_QProcess::throwInChildProcessModifier()::MyException";
+ struct MyException : std::exception {
+ const char *what() const noexcept override { return What; }
+ };
+ QProcess process;
+ process.setChildProcessModifier([]() {
+ throw MyException();
+ });
+ process.setProgram("testProcessNormal/testProcessNormal");
+
+ process.start();
+ QVERIFY(!process.waitForStarted(5000));
+ QCOMPARE(process.state(), QProcess::NotRunning);
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QVERIFY2(process.errorString().contains("Child process modifier threw an exception"),
+ qPrintable(process.errorString()));
+ QVERIFY2(process.errorString().contains(What),
+ qPrintable(process.errorString()));
+
+ // try again, to ensure QProcess internal state wasn't corrupted
+ process.start();
+ QVERIFY(!process.waitForStarted(5000));
+ QCOMPARE(process.state(), QProcess::NotRunning);
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QVERIFY2(process.errorString().contains("Child process modifier threw an exception"),
+ qPrintable(process.errorString()));
+ QVERIFY2(process.errorString().contains(What),
+ qPrintable(process.errorString()));
+#endif
+}
+
+void tst_QProcess::terminateInChildProcessModifier_data()
+{
+ using F = std::function<void(void)>;
+ QTest::addColumn<F>("function");
+ QTest::addColumn<QProcess::ExitStatus>("exitStatus");
+ QTest::addColumn<bool>("stderrIsEmpty");
+
+ QTest::newRow("_exit") << F([]() { _exit(0); }) << QProcess::NormalExit << true;
+ QTest::newRow("abort") << F(std::abort) << QProcess::CrashExit << true;
+ QTest::newRow("sigkill") << F([]() { raise(SIGKILL); }) << QProcess::CrashExit << true;
+ QTest::newRow("terminate") << F(std::terminate) << QProcess::CrashExit
+ << (std::get_terminate() == std::abort);
+ QTest::newRow("crash") << F([]() { tst_QProcessCrash::crash(); }) << QProcess::CrashExit << true;
+}
+
+void tst_QProcess::terminateInChildProcessModifier()
+{
+ QFETCH(std::function<void(void)>, function);
+ QFETCH(QProcess::ExitStatus, exitStatus);
+ QFETCH(bool, stderrIsEmpty);
+
+ // temporarily disable QTest's crash logger
+ DisableCrashLogger disableCrashLogging;
+
+ // testForwardingHelper prints to both stdout and stderr, so if we fail to
+ // fail we should be able to tell too
+ QProcess process;
+ process.setChildProcessModifier(function);
+ process.setProgram("testForwardingHelper/testForwardingHelper");
+ process.setArguments({ "/dev/null" });
+
+ // temporarily disable QTest's crash logger while starting the child process
+ {
+ DisableCrashLogger d;
+ process.start();
+ }
+
+ QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString()));
+ QVERIFY2(process.waitForFinished(5000), qPrintable(process.errorString()));
+ QCOMPARE(process.exitStatus(), exitStatus);
+ QCOMPARE(process.readAllStandardOutput(), QByteArray());
+
+ // some environments print extra stuff to stderr when we crash
+#ifndef Q_OS_QNX
+ if (!QTestPrivate::isRunningArmOnX86()) {
+ QByteArray standardError = process.readAllStandardError();
+ QVERIFY2(standardError.isEmpty() == stderrIsEmpty,
+ "stderr was: " + standardError);
+ }
+#endif
+}
+
+void tst_QProcess::raiseInChildProcessModifier()
+{
+#ifdef QT_BUILD_INTERNAL
+ // This is similar to the above, but knowing that raise() doesn't unblock
+ // signals, unlike abort(), this implies that
+ // 1) the raise() in the child modifier will not run our handler
+ // 2) the write() to stdout after that will run
+ // 3) QProcess resets the signal handlers to the defaults, then unblocks
+ // 4) at that point, the signal will be delivered to the child, but our
+ // handler is no longer active so there'll be no write() to stderr
+ //
+ // Note for maintenance: if in the future this test causes the parent
+ // process to die with SIGUSR1, it means the C library is buggy and is
+ // using a cached PID in the child process after vfork().
+ if (!QT_PREPEND_NAMESPACE(_qprocessUsingVfork()))
+ QSKIP("QProcess will only block Unix signals when using vfork()");
+
+ // we use SIGUSR1 because QtTest doesn't log it and because its default
+ // action is termination, not core dumping
+ struct SigUsr1Handler {
+ SigUsr1Handler()
+ {
+ struct sigaction sa = {};
+ sa.sa_flags = SA_RESETHAND;
+ sa.sa_handler = [](int) {
+ static const char msg[] = "SIGUSR1 handler was run";
+ write(STDERR_FILENO, msg, strlen(msg));
+ raise(SIGUSR1); // re-raise
+ };
+ sigaction(SIGUSR1, &sa, nullptr);
+ }
+ ~SigUsr1Handler() { restore(); }
+ static void restore() { signal(SIGUSR1, SIG_DFL); }
+ } sigUsr1Handler;
+
+ QProcess process;
+
+ // QProcess will block signals with UseVFork
+ process.setUnixProcessParameters(QProcess::UnixProcessFlag::UseVFork |
+ QProcess::UnixProcessFlag::ResetSignalHandlers);
+ process.setChildProcessModifier([]() {
+ raise(SIGUSR1);
+ ::childProcessModifier(STDOUT_FILENO);
+ });
+
+ // testForwardingHelper prints to both stdout and stderr, so if we fail to
+ // fail we should be able to tell too
+ process.setProgram("testForwardingHelper/testForwardingHelper");
+ process.setArguments({ "/dev/null" });
+
+ process.start();
+ QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString()));
+ QVERIFY2(process.waitForFinished(5000), qPrintable(process.errorString()));
+ QCOMPARE(process.error(), QProcess::Crashed);
+
+ // ensure the write() from the child modifier DID get run
+ QCOMPARE(process.readAllStandardOutput(), messageFromChildProcess);
+
+ // some environments print extra stuff to stderr when we crash
+ if (!QTestPrivate::isRunningArmOnX86()) {
+ // and write() from the SIGUSR1 handler did not
+ QCOMPARE(process.readAllStandardError(), QByteArray());
+ }
+#else
+ QSKIP("Requires QT_BUILD_INTERNAL symbols");
+#endif
+}
+
+void tst_QProcess::unixProcessParameters_data()
+{
+ QTest::addColumn<QProcess::UnixProcessParameters>("params");
+ QTest::addColumn<QString>("cmd");
+ QTest::newRow("defaults") << QProcess::UnixProcessParameters{} << QString();
+
+ auto addRow = [](const char *cmd, QProcess::UnixProcessFlags flags) {
+ QProcess::UnixProcessParameters params = {};
+ params.flags = flags;
+ QTest::addRow("%s", cmd) << params << cmd;
+ };
+ using P = QProcess::UnixProcessFlag;
+ addRow("reset-sighand", P::ResetSignalHandlers);
+ addRow("ignore-sigpipe", P::IgnoreSigPipe);
+ addRow("file-descriptors", P::CloseFileDescriptors);
+ addRow("setsid", P::CreateNewSession);
+ addRow("reset-ids", P::ResetIds);
+
+ // On FreeBSD, we need to be session leader to disconnect from the CTTY
+ addRow("noctty", P::DisconnectControllingTerminal | P::CreateNewSession);
+}
+
+void tst_QProcess::unixProcessParameters()
+{
+ QFETCH(QProcess::UnixProcessParameters, params);
+ QFETCH(QString, cmd);
+
+ // set up a few things
+ struct Scope {
+ int devnull;
+ struct sigaction old_sigusr1, old_sigpipe;
+ Scope()
+ {
+ int fd = open("/dev/null", O_RDONLY);
+ devnull = fcntl(fd, F_DUPFD, 100);
+ close(fd);
+
+ // we ignore SIGUSR1 and reset SIGPIPE to Terminate
+ struct sigaction act = {};
+ sigemptyset(&act.sa_mask);
+ act.sa_handler = SIG_IGN;
+ sigaction(SIGUSR1, &act, &old_sigusr1);
+ act.sa_handler = SIG_DFL;
+ sigaction(SIGPIPE, &act, &old_sigpipe);
+
+ // and we block SIGUSR2
+ sigset_t *set = &act.sa_mask; // reuse this sigset_t
+ sigaddset(set, SIGUSR2);
+ sigprocmask(SIG_BLOCK, set, nullptr);
+ }
+ ~Scope()
+ {
+ if (devnull != -1)
+ dismiss();
+ }
+ void dismiss()
+ {
+ close(devnull);
+ sigaction(SIGUSR1, &old_sigusr1, nullptr);
+ sigaction(SIGPIPE, &old_sigpipe, nullptr);
+ devnull = -1;
+
+ sigset_t *set = &old_sigusr1.sa_mask; // reuse this sigset_t
+ sigaddset(set, SIGUSR2);
+ sigprocmask(SIG_BLOCK, set, nullptr);
+ }
+ } scope;
+
+ if (params.flags & QProcess::UnixProcessFlag::ResetIds) {
+ if (getuid() == geteuid() && getgid() == getegid())
+ qInfo("Process has identical real and effective IDs; this test will do nothing");
+ }
+
+ if (params.flags & QProcess::UnixProcessFlag::DisconnectControllingTerminal) {
+ if (int fd = open("/dev/tty", O_RDONLY); fd < 0) {
+ qInfo("Process has no controlling terminal; this test will do nothing");
+ close(fd);
+ }
+ }
+
+ QProcess process;
+ process.setUnixProcessParameters(params);
+ process.setStandardInputFile(QProcess::nullDevice()); // so we can't mess with SIGPIPE
+ process.setProgram("testUnixProcessParameters/testUnixProcessParameters");
+ process.setArguments({ cmd, QString::number(scope.devnull) });
+ process.start();
+ QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString()));
+ QVERIFY(process.waitForFinished(5000));
+
+ const QString stdErr = process.readAllStandardError();
+ QCOMPARE(stdErr, QString());
+ QCOMPARE(process.readAll(), QString());
+ QCOMPARE(process.exitCode(), 0);
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+}
+
+void tst_QProcess::impossibleUnixProcessParameters_data()
+{
+ using P = QProcess::UnixProcessParameters;
+ QTest::addColumn<P>("params");
+ QTest::newRow("setsid") << P{ QProcess::UnixProcessFlag::CreateNewSession };
+}
+
+void tst_QProcess::impossibleUnixProcessParameters()
+{
+ QFETCH(QProcess::UnixProcessParameters, params);
+
+ QProcess process;
+ if (params.flags & QProcess::UnixProcessFlag::CreateNewSession) {
+ process.setChildProcessModifier([]() {
+ // double setsid() should cause the second to fail
+ setsid();
+ });
+ }
+ process.setUnixProcessParameters(params);
+ process.start("testProcessNormal/testProcessNormal");
+
+ QVERIFY(!process.waitForStarted(5000));
+ qDebug() << process.errorString();
+}
+
+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];
+
+ pid_t oldpgid = getpgrp();
+
+ QVERIFY2(pipe(pipes) == 0, qPrintable(qt_error_string()));
+ auto pipeGuard0 = qScopeGuard([=] { close(pipes[0]); });
+ {
+ auto pipeGuard1 = qScopeGuard([=] { close(pipes[1]); });
+
+ // verify that our modifier runs before the parameters are applied
+ process.setChildProcessModifier([=, &vforkControl] {
+ const char *pgidmsg = "PGID mismatch. ";
+ if (getpgrp() != oldpgid)
+ write(pipes[1], pgidmsg, strlen(pgidmsg));
+ write(pipes[1], message, strlen(message));
+ vforkControl.storeRelaxed(1);
+ });
+ auto flags = QProcess::UnixProcessFlag::CloseFileDescriptors |
+ QProcess::UnixProcessFlag::CreateNewSession |
+ QProcess::UnixProcessFlag::UseVFork;
+ process.setUnixProcessParameters({ flags });
+ process.setProgram("testUnixProcessParameters/testUnixProcessParameters");
+ process.setArguments({ "file-descriptors", QString::number(pipes[1]) });
+ process.start();
+ QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString()));
+ } // closes the writing end of the pipe
+
+ QVERIFY(process.waitForFinished(5000));
+ QCOMPARE(process.readAllStandardError(), QString());
+ QCOMPARE(process.readAll(), QString());
+
+ char buf[2 * sizeof(message)];
+ 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()");
+}
+
+void tst_QProcess::unixProcessParametersOtherFileDescriptors()
+{
+ constexpr int TargetFileDescriptor = 3;
+ int fd1 = open("/dev/null", O_RDONLY);
+ int devnull = fcntl(fd1, F_DUPFD, 100); // instead of F_DUPFD_CLOEXEC
+ close(fd1);
+
+ auto closeFds = qScopeGuard([&] {
+ close(devnull);
+ });
+
+ QProcess process;
+ QProcess::UnixProcessParameters params;
+ params.flags = QProcess::UnixProcessFlag::CloseFileDescriptors
+ | QProcess::UnixProcessFlag::UseVFork;
+ params.lowestFileDescriptorToClose = 4;
+ process.setUnixProcessParameters(params);
+ process.setChildProcessModifier([devnull, &process]() {
+ if (dup2(devnull, TargetFileDescriptor) != TargetFileDescriptor)
+ process.failChildProcessModifier("dup2", errno);
+ });
+ process.setProgram("testUnixProcessParameters/testUnixProcessParameters");
+ process.setArguments({ "file-descriptors2", QString::number(TargetFileDescriptor),
+ QString::number(devnull) });
+ process.start();
+
+ QVERIFY2(process.waitForStarted(5000), qPrintable(process.errorString()));
+ QVERIFY(process.waitForFinished(5000));
+ QCOMPARE(process.readAllStandardError(), QString());
+ QCOMPARE(process.readAll(), QString());
+ QCOMPARE(process.exitCode(), 0);
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+}
+#endif
+
void tst_QProcess::exitCodeTest()
{
for (int i = 0; i < 255; ++i) {
QProcess process;
- process.start("testExitCodes/testExitCodes " + QString::number(i));
+ process.start("testExitCodes/testExitCodes", {QString::number(i)});
QVERIFY(process.waitForFinished(5000));
QCOMPARE(process.exitCode(), i);
QCOMPARE(process.error(), QProcess::UnknownError);
@@ -1490,25 +1979,16 @@ void tst_QProcess::failToStart()
QProcess process;
QSignalSpy stateSpy(&process, &QProcess::stateChanged);
QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
- QSignalSpy finishedSpy(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished));
+ QSignalSpy finishedSpy(&process, &QProcess::finished);
QVERIFY(stateSpy.isValid());
QVERIFY(errorSpy.isValid());
QVERIFY(finishedSpy.isValid());
-#if QT_DEPRECATED_SINCE(5, 6)
- QSignalSpy errorSpy2(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
- QVERIFY(errorSpy2.isValid());
-#endif
-#if QT_DEPRECATED_SINCE(5, 13)
- QSignalSpy finishedSpy2(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished));
- QVERIFY(finishedSpy2.isValid());
-#endif
-
// OS X and HP-UX have a really low default process limit (~100), so spawning
// to many processes here will cause test failures later on.
#if defined Q_OS_HPUX
const int attempts = 15;
-#elif defined Q_OS_MAC
+#elif defined Q_OS_DARWIN
const int attempts = 15;
#else
const int attempts = 50;
@@ -1516,10 +1996,7 @@ void tst_QProcess::failToStart()
for (int j = 0; j < 8; ++j) {
for (int i = 0; i < attempts; ++i) {
- QCOMPARE(errorSpy.count(), j * attempts + i);
-#if QT_DEPRECATED_SINCE(5, 6)
- QCOMPARE(errorSpy2.count(), j * attempts + i);
-#endif
+ QCOMPARE(errorSpy.size(), j * attempts + i);
process.start("/blurp");
switch (j) {
@@ -1543,18 +2020,12 @@ void tst_QProcess::failToStart()
}
QCOMPARE(process.error(), QProcess::FailedToStart);
- QCOMPARE(errorSpy.count(), j * attempts + i + 1);
- QCOMPARE(finishedSpy.count(), 0);
-#if QT_DEPRECATED_SINCE(5, 6)
- QCOMPARE(errorSpy2.count(), j * attempts + i + 1);
-#endif
-#if QT_DEPRECATED_SINCE(5, 13)
- QCOMPARE(finishedSpy2.count(), 0);
-#endif
+ QCOMPARE(errorSpy.size(), j * attempts + i + 1);
+ QCOMPARE(finishedSpy.size(), 0);
int it = j * attempts + i + 1;
- QCOMPARE(stateSpy.count(), it * 2);
+ QCOMPARE(stateSpy.size(), it * 2);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(stateSpy.at(it * 2 - 2).at(0)), QProcess::Starting);
QCOMPARE(qvariant_cast<QProcess::ProcessState>(stateSpy.at(it * 2 - 1).at(0)), QProcess::NotRunning);
}
@@ -1569,33 +2040,17 @@ void tst_QProcess::failToStartWithWait()
QProcess process;
QEventLoop loop;
QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
- QSignalSpy finishedSpy(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished));
+ QSignalSpy finishedSpy(&process, &QProcess::finished);
QVERIFY(errorSpy.isValid());
QVERIFY(finishedSpy.isValid());
-#if QT_DEPRECATED_SINCE(5, 6)
- QSignalSpy errorSpy2(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
- QVERIFY(errorSpy2.isValid());
-#endif
-#if QT_DEPRECATED_SINCE(5, 13)
- QSignalSpy finishedSpy2(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished));
- QVERIFY(finishedSpy2.isValid());
-#endif
-
for (int i = 0; i < 50; ++i) {
process.start("/blurp", QStringList() << "-v" << "-debug");
process.waitForStarted();
QCOMPARE(process.error(), QProcess::FailedToStart);
- QCOMPARE(errorSpy.count(), i + 1);
- QCOMPARE(finishedSpy.count(), 0);
-#if QT_DEPRECATED_SINCE(5, 6)
- QCOMPARE(errorSpy2.count(), i + 1);
-#endif
-#if QT_DEPRECATED_SINCE(5, 13)
- QCOMPARE(finishedSpy2.count(), 0);
-#endif
-
+ QCOMPARE(errorSpy.size(), i + 1);
+ QCOMPARE(finishedSpy.size(), 0);
}
}
@@ -1607,19 +2062,10 @@ void tst_QProcess::failToStartWithEventLoop()
QProcess process;
QEventLoop loop;
QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
- QSignalSpy finishedSpy(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished));
+ QSignalSpy finishedSpy(&process, &QProcess::finished);
QVERIFY(errorSpy.isValid());
QVERIFY(finishedSpy.isValid());
-#if QT_DEPRECATED_SINCE(5, 6)
- QSignalSpy errorSpy2(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
- QVERIFY(errorSpy2.isValid());
-#endif
-#if QT_DEPRECATED_SINCE(5, 13)
- QSignalSpy finishedSpy2(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished));
- QVERIFY(finishedSpy2.isValid());
-#endif
-
// The error signal may be emitted before start() returns
connect(&process, &QProcess::errorOccurred, &loop, &QEventLoop::quit, Qt::QueuedConnection);
@@ -1630,14 +2076,8 @@ void tst_QProcess::failToStartWithEventLoop()
loop.exec();
QCOMPARE(process.error(), QProcess::FailedToStart);
- QCOMPARE(errorSpy.count(), i + 1);
- QCOMPARE(finishedSpy.count(), 0);
-#if QT_DEPRECATED_SINCE(5, 6)
- QCOMPARE(errorSpy2.count(), i + 1);
-#endif
-#if QT_DEPRECATED_SINCE(5, 13)
- QCOMPARE(finishedSpy2.count(), 0);
-#endif
+ QCOMPARE(errorSpy.size(), i + 1);
+ QCOMPARE(finishedSpy.size(), 0);
}
}
@@ -1645,8 +2085,7 @@ void tst_QProcess::failToStartEmptyArgs_data()
{
QTest::addColumn<int>("startOverload");
QTest::newRow("start(QString, QStringList, OpenMode)") << 0;
- QTest::newRow("start(QString, OpenMode)") << 1;
- QTest::newRow("start(OpenMode)") << 2;
+ QTest::newRow("start(OpenMode)") << 1;
}
void tst_QProcess::failToStartEmptyArgs()
@@ -1657,19 +2096,12 @@ void tst_QProcess::failToStartEmptyArgs()
QProcess process;
QSignalSpy errorSpy(&process, static_cast<QProcessErrorSignal>(&QProcess::errorOccurred));
QVERIFY(errorSpy.isValid());
-#if QT_DEPRECATED_SINCE(5, 6)
- QSignalSpy errorSpy2(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
- QVERIFY(errorSpy2.isValid());
-#endif
switch (startOverload) {
case 0:
process.start(QString(), QStringList(), QIODevice::ReadWrite);
break;
case 1:
- process.start(QString(), QIODevice::ReadWrite);
- break;
- case 2:
process.start(QIODevice::ReadWrite);
break;
default:
@@ -1677,10 +2109,7 @@ void tst_QProcess::failToStartEmptyArgs()
};
QVERIFY(!process.waitForStarted());
- QCOMPARE(errorSpy.count(), 1);
-#if QT_DEPRECATED_SINCE(5, 6)
- QCOMPARE(errorSpy2.count(), 1);
-#endif
+ QCOMPARE(errorSpy.size(), 1);
QCOMPARE(process.error(), QProcess::FailedToStart);
}
@@ -1737,9 +2166,9 @@ void tst_QProcess::setEnvironment()
QStringList environment = QProcess::systemEnvironment();
if (value.isNull()) {
int pos;
- QRegExp rx(name + "=.*");
+ QRegularExpression rx(name + "=.*");
#ifdef Q_OS_WIN
- rx.setCaseSensitivity(Qt::CaseInsensitive);
+ rx.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
#endif
while ((pos = environment.indexOf(rx)) != -1)
environment.removeAt(pos);
@@ -1862,7 +2291,7 @@ void tst_QProcess::systemEnvironment()
QVERIFY(!QProcessEnvironment::systemEnvironment().isEmpty());
QVERIFY(QProcessEnvironment::systemEnvironment().contains("PATH"));
- QVERIFY(!QProcess::systemEnvironment().filter(QRegExp("^PATH=", Qt::CaseInsensitive)).isEmpty());
+ QVERIFY(!QProcess::systemEnvironment().filter(QRegularExpression("^PATH=", QRegularExpression::CaseInsensitiveOption)).isEmpty());
}
void tst_QProcess::spaceInName()
@@ -1912,32 +2341,16 @@ void tst_QProcess::waitForReadyReadForNonexistantProcess()
QProcess process;
QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
- QSignalSpy finishedSpy(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished));
+ QSignalSpy finishedSpy(&process, &QProcess::finished);
QVERIFY(errorSpy.isValid());
QVERIFY(finishedSpy.isValid());
-#if QT_DEPRECATED_SINCE(5, 6)
- QSignalSpy errorSpy2(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
- QVERIFY(errorSpy2.isValid());
-#endif
-#if QT_DEPRECATED_SINCE(5, 13)
- QSignalSpy finishedSpy1(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished));
- QVERIFY(finishedSpy1.isValid());
-#endif
-
QVERIFY(!process.waitForReadyRead()); // used to crash
process.start("doesntexist");
QVERIFY(!process.waitForReadyRead());
- QCOMPARE(errorSpy.count(), 1);
+ QCOMPARE(errorSpy.size(), 1);
QCOMPARE(errorSpy.at(0).at(0).toInt(), 0);
- QCOMPARE(finishedSpy.count(), 0);
-#if QT_DEPRECATED_SINCE(5, 6)
- QCOMPARE(errorSpy2.count(), 1);
- QCOMPARE(errorSpy2.at(0).at(0).toInt(), 0);
-#endif
-#if QT_DEPRECATED_SINCE(5, 13)
- QCOMPARE(finishedSpy1.count(), 0);
-#endif
+ QCOMPARE(finishedSpy.size(), 0);
}
void tst_QProcess::setStandardInputFile()
@@ -1946,12 +2359,21 @@ void tst_QProcess::setStandardInputFile()
QProcess process;
QFile file(m_temporaryDir.path() + QLatin1String("/data-sif"));
+ QSignalSpy stateSpy(&process, &QProcess::stateChanged);
+ QSignalSpy errorOccurredSpy(&process, &QProcess::errorOccurred);
+
QVERIFY(file.open(QIODevice::WriteOnly));
file.write(data, sizeof data);
file.close();
process.setStandardInputFile(file.fileName());
process.start("testProcessEcho/testProcessEcho");
+ QVERIFY(process.waitForStarted());
+ QCOMPARE(errorOccurredSpy.size(), 0);
+ QCOMPARE(stateSpy.size(), 2);
+ QCOMPARE(stateSpy[0][0].value<QProcess::ProcessState>(), QProcess::Starting);
+ QCOMPARE(stateSpy[1][0].value<QProcess::ProcessState>(), QProcess::Running);
+ stateSpy.clear();
QVERIFY(process.waitForFinished());
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
@@ -1968,31 +2390,50 @@ void tst_QProcess::setStandardInputFile()
QCOMPARE(all.size(), 0);
}
+void tst_QProcess::setStandardInputFileFailure()
+{
+ QProcess process;
+ process.setStandardInputFile(nonExistentFileName);
+
+ QSignalSpy stateSpy(&process, &QProcess::stateChanged);
+ QSignalSpy errorOccurredSpy(&process, &QProcess::errorOccurred);
+
+ process.start("testProcessEcho/testProcessEcho");
+ QVERIFY(!process.waitForStarted());
+
+ QCOMPARE(errorOccurredSpy.size(), 1);
+ QCOMPARE(errorOccurredSpy[0][0].value<QProcess::ProcessError>(), QProcess::FailedToStart);
+
+ QCOMPARE(stateSpy.size(), 2);
+ QCOMPARE(stateSpy[0][0].value<QProcess::ProcessState>(), QProcess::Starting);
+ QCOMPARE(stateSpy[1][0].value<QProcess::ProcessState>(), QProcess::NotRunning);
+}
+
void tst_QProcess::setStandardOutputFile_data()
{
- QTest::addColumn<int>("channelToTest");
- QTest::addColumn<int>("_channelMode");
+ QTest::addColumn<QProcess::ProcessChannel>("channelToTest");
+ QTest::addColumn<QProcess::ProcessChannelMode>("channelMode");
QTest::addColumn<bool>("append");
- QTest::newRow("stdout-truncate") << int(QProcess::StandardOutput)
- << int(QProcess::SeparateChannels)
+ QTest::newRow("stdout-truncate") << QProcess::StandardOutput
+ << QProcess::SeparateChannels
<< false;
- QTest::newRow("stdout-append") << int(QProcess::StandardOutput)
- << int(QProcess::SeparateChannels)
+ QTest::newRow("stdout-append") << QProcess::StandardOutput
+ << QProcess::SeparateChannels
<< true;
- QTest::newRow("stderr-truncate") << int(QProcess::StandardError)
- << int(QProcess::SeparateChannels)
+ QTest::newRow("stderr-truncate") << QProcess::StandardError
+ << QProcess::SeparateChannels
<< false;
- QTest::newRow("stderr-append") << int(QProcess::StandardError)
- << int(QProcess::SeparateChannels)
+ QTest::newRow("stderr-append") << QProcess::StandardError
+ << QProcess::SeparateChannels
<< true;
- QTest::newRow("merged-truncate") << int(QProcess::StandardOutput)
- << int(QProcess::MergedChannels)
+ QTest::newRow("merged-truncate") << QProcess::StandardOutput
+ << QProcess::MergedChannels
<< false;
- QTest::newRow("merged-append") << int(QProcess::StandardOutput)
- << int(QProcess::MergedChannels)
+ QTest::newRow("merged-append") << QProcess::StandardOutput
+ << QProcess::MergedChannels
<< true;
}
@@ -2001,11 +2442,10 @@ void tst_QProcess::setStandardOutputFile()
static const char data[] = "Original data. ";
static const char testdata[] = "Test data.";
- QFETCH(int, channelToTest);
- QFETCH(int, _channelMode);
+ QFETCH(QProcess::ProcessChannel, channelToTest);
+ QFETCH(QProcess::ProcessChannelMode, channelMode);
QFETCH(bool, append);
- QProcess::ProcessChannelMode channelMode = QProcess::ProcessChannelMode(_channelMode);
QIODevice::OpenMode mode = append ? QIODevice::Append : QIODevice::Truncate;
// create the destination file with data
@@ -2022,7 +2462,17 @@ void tst_QProcess::setStandardOutputFile()
else
process.setStandardErrorFile(file.fileName(), mode);
+ QSignalSpy stateSpy(&process, &QProcess::stateChanged);
+ QSignalSpy errorOccurredSpy(&process, &QProcess::errorOccurred);
+
process.start("testProcessEcho2/testProcessEcho2");
+ QVERIFY(process.waitForStarted());
+ QCOMPARE(errorOccurredSpy.size(), 0);
+ QCOMPARE(stateSpy.size(), 2);
+ QCOMPARE(stateSpy[0][0].value<QProcess::ProcessState>(), QProcess::Starting);
+ QCOMPARE(stateSpy[1][0].value<QProcess::ProcessState>(), QProcess::Running);
+ stateSpy.clear();
+
process.write(testdata, sizeof testdata);
QVERIFY(process.waitForFinished());
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
@@ -2047,6 +2497,34 @@ void tst_QProcess::setStandardOutputFile()
QCOMPARE(all.size(), expectedsize);
}
+void tst_QProcess::setStandardOutputFileFailure()
+{
+ QFETCH(QProcess::ProcessChannel, channelToTest);
+ QFETCH(QProcess::ProcessChannelMode, channelMode);
+ QFETCH(bool, append);
+
+ QIODevice::OpenMode mode = append ? QIODevice::Append : QIODevice::Truncate;
+
+ // run the process
+ QProcess process;
+ process.setProcessChannelMode(channelMode);
+ if (channelToTest == QProcess::StandardOutput)
+ process.setStandardOutputFile(nonExistentFileName, mode);
+ else
+ process.setStandardErrorFile(nonExistentFileName, mode);
+
+ QSignalSpy stateSpy(&process, &QProcess::stateChanged);
+ QSignalSpy errorOccurredSpy(&process, &QProcess::errorOccurred);
+
+ process.start("testProcessEcho2/testProcessEcho2");
+ QVERIFY(!process.waitForStarted());
+ QCOMPARE(errorOccurredSpy.size(), 1);
+ QCOMPARE(errorOccurredSpy[0][0].value<QProcess::ProcessError>(), QProcess::FailedToStart);
+ QCOMPARE(stateSpy.size(), 2);
+ QCOMPARE(stateSpy[0][0].value<QProcess::ProcessState>(), QProcess::Starting);
+ QCOMPARE(stateSpy[1][0].value<QProcess::ProcessState>(), QProcess::NotRunning);
+}
+
void tst_QProcess::setStandardOutputFileNullDevice()
{
static const char testdata[] = "Test data.";
@@ -2098,14 +2576,18 @@ void tst_QProcess::setStandardOutputProcess_data()
void tst_QProcess::setStandardOutputProcess()
{
QProcess source;
+ QProcess intermediate;
QProcess sink;
QFETCH(bool, merged);
QFETCH(bool, waitForBytesWritten);
source.setProcessChannelMode(merged ? QProcess::MergedChannels : QProcess::SeparateChannels);
- source.setStandardOutputProcess(&sink);
+ source.setStandardOutputProcess(&intermediate);
+ intermediate.setStandardOutputProcess(&sink);
source.start("testProcessEcho2/testProcessEcho2");
+ intermediate.setProgram("testProcessEcho/testProcessEcho");
+ QVERIFY(intermediate.startDetached());
sink.start("testProcessEcho2/testProcessEcho2");
QByteArray data("Hello, World");
@@ -2147,7 +2629,7 @@ void tst_QProcess::fileWriterProcess()
QVERIFY(QFile::remove(fileName));
QProcess process;
process.setWorkingDirectory(m_temporaryDir.path());
- process.start(binary, QIODevice::ReadWrite | QIODevice::Text);
+ process.start(binary, {}, QIODevice::ReadWrite | QIODevice::Text);
process.write(stdinStr);
process.closeWriteChannel();
while (process.bytesToWrite()) {
@@ -2318,18 +2800,48 @@ void tst_QProcess::setWorkingDirectory()
void tst_QProcess::setNonExistentWorkingDirectory()
{
QProcess process;
- process.setWorkingDirectory("this/directory/should/not/exist/for/sure");
+ process.setWorkingDirectory(nonExistentFileName);
+
+ QSignalSpy stateSpy(&process, &QProcess::stateChanged);
+ QSignalSpy errorOccurredSpy(&process, &QProcess::errorOccurred);
// 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.start(QFileInfo("testSetWorkingDirectory/testSetWorkingDirectory").absoluteFilePath());
+
QVERIFY(!process.waitForFinished());
- QCOMPARE(int(process.error()), int(QProcess::FailedToStart));
+ QCOMPARE(errorOccurredSpy.size(), 1);
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QCOMPARE(stateSpy.size(), 2);
+ QCOMPARE(stateSpy[0][0].value<QProcess::ProcessState>(), QProcess::Starting);
+ QCOMPARE(stateSpy[1][0].value<QProcess::ProcessState>(), QProcess::NotRunning);
+
+#ifdef Q_OS_UNIX
+ QVERIFY2(process.errorString().startsWith("chdir:"), process.errorString().toLocal8Bit());
+#endif
+}
+
+void tst_QProcess::detachedSetNonExistentWorkingDirectory()
+{
+ QProcess process;
+ process.setWorkingDirectory(nonExistentFileName);
+
+ QSignalSpy errorOccurredSpy(&process, &QProcess::errorOccurred);
+
+ // 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);
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QVERIFY(process.errorString() != "Unknown error");
+
+ QCOMPARE(errorOccurredSpy.size(), 1);
+ QCOMPARE(process.error(), QProcess::FailedToStart);
#ifdef Q_OS_UNIX
-# ifdef QPROCESS_USE_SPAWN
- QEXPECT_FAIL("", "QProcess cannot detect failure to start when using posix_spawn()", Continue);
-# endif
QVERIFY2(process.errorString().startsWith("chdir:"), process.errorString().toLocal8Bit());
#endif
}
@@ -2358,7 +2870,6 @@ void tst_QProcess::invalidProgramString_data()
QTest::addColumn<QString>("programString");
QTest::newRow("null string") << QString();
QTest::newRow("empty string") << QString("");
- QTest::newRow("only blank string") << QString(" ");
}
void tst_QProcess::invalidProgramString()
@@ -2369,17 +2880,10 @@ void tst_QProcess::invalidProgramString()
qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
QSignalSpy spy(&process, &QProcess::errorOccurred);
QVERIFY(spy.isValid());
-#if QT_DEPRECATED_SINCE(5, 6)
- QSignalSpy spy2(&process, static_cast<QProcessErrorSignal>(&QProcess::error));
- QVERIFY(spy2.isValid());
-#endif
process.start(programString);
QCOMPARE(process.error(), QProcess::FailedToStart);
- QCOMPARE(spy.count(), 1);
-#if QT_DEPRECATED_SINCE(5, 6)
- QCOMPARE(spy2.count(), 1);
-#endif
+ QCOMPARE(spy.size(), 1);
QVERIFY(!QProcess::startDetached(programString));
}
@@ -2390,7 +2894,7 @@ void tst_QProcess::onlyOneStartedSignal()
QProcess process;
QSignalSpy spyStarted(&process, &QProcess::started);
- QSignalSpy spyFinished(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished));
+ QSignalSpy spyFinished(&process, &QProcess::finished);
QVERIFY(spyStarted.isValid());
QVERIFY(spyFinished.isValid());
@@ -2398,8 +2902,8 @@ void tst_QProcess::onlyOneStartedSignal()
process.start("testProcessNormal/testProcessNormal");
QVERIFY(process.waitForStarted(5000));
QVERIFY(process.waitForFinished(5000));
- QCOMPARE(spyStarted.count(), 1);
- QCOMPARE(spyFinished.count(), 1);
+ QCOMPARE(spyStarted.size(), 1);
+ QCOMPARE(spyFinished.size(), 1);
spyStarted.clear();
spyFinished.clear();
@@ -2408,8 +2912,8 @@ void tst_QProcess::onlyOneStartedSignal()
QVERIFY(process.waitForFinished(5000));
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
QCOMPARE(process.exitCode(), 0);
- QCOMPARE(spyStarted.count(), 1);
- QCOMPARE(spyFinished.count(), 1);
+ QCOMPARE(spyStarted.size(), 1);
+ QCOMPARE(spyFinished.size(), 1);
}
class BlockOnReadStdOut : public QObject
@@ -2424,7 +2928,7 @@ public:
public slots:
void block()
{
- QThread::sleep(1);
+ QThread::sleep(std::chrono::seconds{1});
}
};
@@ -2433,13 +2937,12 @@ void tst_QProcess::finishProcessBeforeReadingDone()
QProcess process;
BlockOnReadStdOut blocker(&process);
QEventLoop loop;
- connect(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished),
- &loop, &QEventLoop::quit);
+ connect(&process, &QProcess::finished, &loop, &QEventLoop::quit);
process.start("testProcessOutput/testProcessOutput");
QVERIFY(process.waitForStarted());
loop.exec();
QStringList lines = QString::fromLocal8Bit(process.readAllStandardOutput()).split(
- QRegExp(QStringLiteral("[\r\n]")), QString::SkipEmptyParts);
+ QRegularExpression(QStringLiteral("[\r\n]")), Qt::SkipEmptyParts);
QVERIFY(!lines.isEmpty());
QCOMPARE(lines.last(), QStringLiteral("10239 -this is a number"));
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
@@ -2477,23 +2980,23 @@ void tst_QProcess::startStopStartStop()
//-----------------------------------------------------------------------------
void tst_QProcess::startStopStartStopBuffers_data()
{
- QTest::addColumn<int>("channelMode1");
- QTest::addColumn<int>("channelMode2");
+ QTest::addColumn<QProcess::ProcessChannelMode>("channelMode1");
+ QTest::addColumn<QProcess::ProcessChannelMode>("channelMode2");
- QTest::newRow("separate-separate") << int(QProcess::SeparateChannels) << int(QProcess::SeparateChannels);
- QTest::newRow("separate-merged") << int(QProcess::SeparateChannels) << int(QProcess::MergedChannels);
- QTest::newRow("merged-separate") << int(QProcess::MergedChannels) << int(QProcess::SeparateChannels);
- QTest::newRow("merged-merged") << int(QProcess::MergedChannels) << int(QProcess::MergedChannels);
- QTest::newRow("merged-forwarded") << int(QProcess::MergedChannels) << int(QProcess::ForwardedChannels);
+ QTest::newRow("separate-separate") << QProcess::SeparateChannels << QProcess::SeparateChannels;
+ QTest::newRow("separate-merged") << QProcess::SeparateChannels << QProcess::MergedChannels;
+ QTest::newRow("merged-separate") << QProcess::MergedChannels << QProcess::SeparateChannels;
+ QTest::newRow("merged-merged") << QProcess::MergedChannels << QProcess::MergedChannels;
+ QTest::newRow("merged-forwarded") << QProcess::MergedChannels << QProcess::ForwardedChannels;
}
void tst_QProcess::startStopStartStopBuffers()
{
- QFETCH(int, channelMode1);
- QFETCH(int, channelMode2);
+ QFETCH(QProcess::ProcessChannelMode, channelMode1);
+ QFETCH(QProcess::ProcessChannelMode, channelMode2);
QProcess process;
- process.setProcessChannelMode(QProcess::ProcessChannelMode(channelMode1));
+ process.setProcessChannelMode(channelMode1);
process.start("testProcessHang/testProcessHang");
QVERIFY2(process.waitForReadyRead(), process.errorString().toLocal8Bit());
if (channelMode1 == QProcess::SeparateChannels || channelMode1 == QProcess::ForwardedOutputChannel) {
@@ -2504,14 +3007,18 @@ void tst_QProcess::startStopStartStopBuffers()
}
// We want to test that the write buffer still has bytes after the child
- // exiting. We do that by writing to a child process that never reads. We
- // just have to write more data than a pipe can hold, so that even if
- // QProcess finds the pipe writable (during waitForFinished() or in the
- // QWindowsPipeWriter thread), some data will remain. The worst case I know
- // of is Linux, which defaults to 64 kB of buffer.
+ // exits. We can do that by writing data until the OS stops consuming data,
+ // indicating that the pipe buffers are full. The initial value of 128 kB
+ // should make this loop typicall run only once; the worst case I know of
+ // is Linux, which defaults to 64 kB of buffer.
- process.write(QByteArray(128 * 1024, 'a'));
- QVERIFY(process.bytesToWrite() > 0);
+ QByteArray chunk(128 * 1024, 'a');
+ do {
+ process.write(chunk);
+ QVERIFY(process.bytesToWrite() > 0);
+ process.waitForBytesWritten(1);
+ } while (process.bytesToWrite() == 0);
+ chunk = {};
process.kill();
QVERIFY(process.waitForFinished());
@@ -2519,7 +3026,8 @@ void tst_QProcess::startStopStartStopBuffers()
#ifndef Q_OS_WIN
// confirm that our buffers are still full
// Note: this doesn't work on Windows because our buffers are drained into
- // QWindowsPipeWriter before being sent to the child process.
+ // QWindowsPipeWriter before being sent to the child process and are lost
+ // in waitForFinished() -> processFinished() -> cleanup().
QVERIFY(process.bytesToWrite() > 0);
QVERIFY(process.bytesAvailable() > 0); // channelMode1 is not ForwardedChannels
if (channelMode1 == QProcess::SeparateChannels || channelMode1 == QProcess::ForwardedOutputChannel) {
@@ -2529,8 +3037,8 @@ void tst_QProcess::startStopStartStopBuffers()
}
#endif
- process.setProcessChannelMode(QProcess::ProcessChannelMode(channelMode2));
- process.start("testProcessEcho2/testProcessEcho2", QIODevice::ReadWrite | QIODevice::Text);
+ process.setProcessChannelMode(channelMode2);
+ process.start("testProcessEcho2/testProcessEcho2", {}, QIODevice::ReadWrite | QIODevice::Text);
// the buffers should now be empty
QCOMPARE(process.bytesToWrite(), qint64(0));
@@ -2579,106 +3087,94 @@ void tst_QProcess::processEventsInAReadyReadSlot()
QVERIFY(process.waitForFinished());
}
-#if QT_DEPRECATED_SINCE(5, 13)
+enum class ChdirMode {
+ None = 0,
+ InParent,
+ InChild
+};
+Q_DECLARE_METATYPE(ChdirMode)
-void tst_QProcess::crashTest2_deprecated()
+void tst_QProcess::startFromCurrentWorkingDir_data()
{
- QProcess process;
- process.start("testProcessCrash/testProcessCrash");
- QVERIFY(process.waitForStarted(5000));
-
- qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
- qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
-
- QSignalSpy spy(&process, static_cast<QProcessErrorSignal>(&QProcess::errorOccurred));
- QSignalSpy spy2(&process, static_cast<QProcessFinishedSignal2>(&QProcess::finished));
+ qRegisterMetaType<ChdirMode>();
+ QTest::addColumn<QString>("programPrefix");
+ QTest::addColumn<ChdirMode>("chdirMode");
+ QTest::addColumn<bool>("success");
- QVERIFY(spy.isValid());
- QVERIFY(spy2.isValid());
+ constexpr bool IsWindows = true
+#ifdef Q_OS_UNIX
+ && false
+#endif
+ ;
- QObject::connect(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished),
- this, &tst_QProcess::exitLoopSlot);
+ // baseline: trying to execute the directory, this can't possibly succeed!
+ QTest::newRow("plain-same-cwd") << QString() << ChdirMode::None << false;
- QTestEventLoop::instance().enterLoop(30);
- if (QTestEventLoop::instance().timeout())
- QFAIL("Failed to detect crash : operation timed out");
+ // cross-platform behavior: neither OS searches the setWorkingDirectory()
+ // dir without "./"
+ QTest::newRow("plain-child-chdir") << QString() << ChdirMode::InChild << false;
- QCOMPARE(spy.count(), 1);
- QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
+ // cross-platform behavior: both OSes search the parent's CWD with "./"
+ QTest::newRow("prefixed-parent-chdir") << "./" << ChdirMode::InParent << true;
- QCOMPARE(spy2.count(), 1);
- QCOMPARE(*static_cast<const QProcess::ExitStatus *>(spy2.at(0).at(1).constData()), QProcess::CrashExit);
+ // opposite behaviors: Windows searches the parent's CWD and Unix searches
+ // the child's with "./"
+ QTest::newRow("prefixed-child-chdir") << "./" << ChdirMode::InChild << !IsWindows;
- QCOMPARE(process.exitStatus(), QProcess::CrashExit);
+ // Windows searches the parent's CWD without "./"
+ QTest::newRow("plain-parent-chdir") << QString() << ChdirMode::InParent << IsWindows;
}
-void tst_QProcess::restartProcessDeadlock_deprecated()
+void tst_QProcess::startFromCurrentWorkingDir()
{
- // The purpose of this test is to detect whether restarting a
- // process in the finished() connected slot causes a deadlock
- // because of the way QProcessManager uses its locks.
- QProcess process;
- connect(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished),
- this, &tst_QProcess::restartProcess);
-
- process.start("testProcessEcho/testProcessEcho");
-
- QCOMPARE(process.write("", 1), qlonglong(1));
- QVERIFY(process.waitForFinished(5000));
-
- QObject::disconnect(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished), nullptr, nullptr);
-
- QCOMPARE(process.write("", 1), qlonglong(1));
- QVERIFY(process.waitForFinished(5000));
- QCOMPARE(process.exitStatus(), QProcess::NormalExit);
- QCOMPARE(process.exitCode(), 0);
-}
+ QFETCH(QString, programPrefix);
+ QFETCH(ChdirMode, chdirMode);
+ QFETCH(bool, success);
-void tst_QProcess::waitForReadyReadInAReadyReadSlot_deprecated()
-{
QProcess process;
- connect(&process, &QIODevice::readyRead, this, &tst_QProcess::waitForReadyReadInAReadyReadSlotSlot);
- connect(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished),
- this, &tst_QProcess::exitLoopSlot);
- bytesAvailable = 0;
-
- process.start("testProcessEcho/testProcessEcho");
- QVERIFY(process.waitForStarted(5000));
+ qRegisterMetaType<QProcess::ProcessError>();
+ QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
+ QVERIFY(errorSpy.isValid());
- QSignalSpy spy(&process, &QProcess::readyRead);
- QVERIFY(spy.isValid());
- process.write("foo");
- QTestEventLoop::instance().enterLoop(30);
- QVERIFY(!QTestEventLoop::instance().timeout());
+ // both the dir name and the executable name
+ const QString target = QStringLiteral("testProcessNormal");
+ process.setProgram(programPrefix + target);
- QCOMPARE(spy.count(), 1);
+#ifdef Q_OS_UNIX
+ // Reset PATH, to be sure it doesn't contain . or the empty path.
+ // We can't do this on Windows because DLLs are searched in PATH
+ // and Windows always searches "." anyway.
+ auto restoreEnv = qScopeGuard([old = qgetenv("PATH")] {
+ qputenv("PATH", old);
+ });
+ qputenv("PATH", "/");
+#endif
- process.disconnect();
- QVERIFY(process.waitForFinished(5000));
- QCOMPARE(process.exitStatus(), QProcess::NormalExit);
- QCOMPARE(process.exitCode(), 0);
- QVERIFY(process.bytesAvailable() > bytesAvailable);
-}
+ switch (chdirMode) {
+ case ChdirMode::InParent: {
+ auto restoreCwd = qScopeGuard([old = QDir::currentPath()] {
+ QDir::setCurrent(old);
+ });
+ QVERIFY(QDir::setCurrent(target));
+ process.start();
+ break;
+ }
+ case ChdirMode::InChild:
+ process.setWorkingDirectory(target);
+ Q_FALLTHROUGH();
+ case ChdirMode::None:
+ process.start();
+ break;
+ }
-void tst_QProcess::finishProcessBeforeReadingDone_deprecated()
-{
- QProcess process;
- BlockOnReadStdOut blocker(&process);
- QEventLoop loop;
- connect(&process, static_cast<QProcessFinishedSignal1>(&QProcess::finished),
- &loop, &QEventLoop::quit);
- process.start("testProcessOutput/testProcessOutput");
- QVERIFY(process.waitForStarted());
- loop.exec();
- QStringList lines = QString::fromLocal8Bit(process.readAllStandardOutput()).split(
- QRegExp(QStringLiteral("[\r\n]")), QString::SkipEmptyParts);
- QVERIFY(!lines.isEmpty());
- QCOMPARE(lines.last(), QStringLiteral("10239 -this is a number"));
- QCOMPARE(process.exitStatus(), QProcess::NormalExit);
- QCOMPARE(process.exitCode(), 0);
+ QCOMPARE(process.waitForStarted(), success);
+ QCOMPARE(errorSpy.size(), int(!success));
+ if (success) {
+ QVERIFY(process.waitForFinished());
+ } else {
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ }
}
-#endif
-
QTEST_MAIN(tst_QProcess)
#include "tst_qprocess.moc"