summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/io/qprocess_unix.cpp9
-rw-r--r--tests/auto/corelib/io/qprocess/tst_qprocess.cpp93
-rw-r--r--tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp4
3 files changed, 99 insertions, 7 deletions
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 91005b0b67..9f97bb7af9 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
-** Copyright (C) 2021 Intel Corporation.
+** Copyright (C) 2022 Intel Corporation.
** Copyright (C) 2021 Alex Trotsenko.
** Contact: https://www.qt.io/licensing/
**
@@ -438,9 +438,10 @@ static QString resolveExecutable(const QString &program)
#endif
if (!program.contains(QLatin1Char('/'))) {
- QString exeFilePath = QStandardPaths::findExecutable(program);
- if (!exeFilePath.isEmpty())
- return exeFilePath;
+ // findExecutable() returns its argument if it's an absolute path,
+ // otherwise it searches $PATH; returns empty if not found (we handle
+ // that case much later)
+ return QStandardPaths::findExecutable(program);
}
return program;
}
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
index 63f2a816fc..80005a7284 100644
--- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
-** Copyright (C) 2020 Intel Corporation.
+** Copyright (C) 2022 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -151,6 +151,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)
@@ -2524,5 +2526,94 @@ void tst_QProcess::processEventsInAReadyReadSlot()
QVERIFY(process.waitForFinished());
}
+enum class ChdirMode {
+ None = 0,
+ InParent,
+ InChild
+};
+Q_DECLARE_METATYPE(ChdirMode)
+
+void tst_QProcess::startFromCurrentWorkingDir_data()
+{
+ qRegisterMetaType<ChdirMode>();
+ QTest::addColumn<QString>("programPrefix");
+ QTest::addColumn<ChdirMode>("chdirMode");
+ QTest::addColumn<bool>("success");
+
+ constexpr bool IsWindows = true
+#ifdef Q_OS_UNIX
+ && false
+#endif
+ ;
+
+ // baseline: trying to execute the directory, this can't possibly succeed!
+ QTest::newRow("plain-same-cwd") << QString() << ChdirMode::None << false;
+
+ // cross-platform behavior: neither OS searches the setWorkingDirectory()
+ // dir without "./"
+ QTest::newRow("plain-child-chdir") << QString() << ChdirMode::InChild << false;
+
+ // cross-platform behavior: both OSes search the parent's CWD with "./"
+ QTest::newRow("prefixed-parent-chdir") << "./" << ChdirMode::InParent << true;
+
+ // opposite behaviors: Windows searches the parent's CWD and Unix searches
+ // the child's with "./"
+ QTest::newRow("prefixed-child-chdir") << "./" << ChdirMode::InChild << !IsWindows;
+
+ // Windows searches the parent's CWD without "./"
+ QTest::newRow("plain-parent-chdir") << QString() << ChdirMode::InParent << IsWindows;
+}
+
+void tst_QProcess::startFromCurrentWorkingDir()
+{
+ QFETCH(QString, programPrefix);
+ QFETCH(ChdirMode, chdirMode);
+ QFETCH(bool, success);
+
+ QProcess process;
+ qRegisterMetaType<QProcess::ProcessError>();
+ QSignalSpy errorSpy(&process, &QProcess::errorOccurred);
+ QVERIFY(errorSpy.isValid());
+
+ // both the dir name and the executable name
+ const QString target = QStringLiteral("testProcessNormal");
+ process.setProgram(programPrefix + target);
+
+#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
+
+ 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;
+ }
+
+ QCOMPARE(process.waitForStarted(), success);
+ QCOMPARE(errorSpy.count(), int(!success));
+ if (success) {
+ QVERIFY(process.waitForFinished());
+ } else {
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ }
+}
+
QTEST_MAIN(tst_QProcess)
#include "tst_qprocess.moc"
diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
index 09c80b817d..107c5fdb84 100644
--- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
@@ -1530,7 +1530,7 @@ void tst_QApplication::desktopSettingsAware()
environment += QLatin1String("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM=1");
testProcess.setEnvironment(environment);
#endif
- testProcess.start("desktopsettingsaware_helper");
+ testProcess.start("./desktopsettingsaware_helper");
QVERIFY2(testProcess.waitForStarted(),
qPrintable(QString::fromLatin1("Cannot start 'desktopsettingsaware_helper': %1").arg(testProcess.errorString())));
QVERIFY(testProcess.waitForFinished(10000));
@@ -2470,7 +2470,7 @@ void tst_QApplication::qtbug_12673()
#if QT_CONFIG(process)
QProcess testProcess;
QStringList arguments;
- testProcess.start("modal_helper", arguments);
+ testProcess.start("./modal_helper", arguments);
QVERIFY2(testProcess.waitForStarted(),
qPrintable(QString::fromLatin1("Cannot start 'modal_helper': %1").arg(testProcess.errorString())));
QVERIFY(testProcess.waitForFinished(20000));