summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2017-12-09 22:18:02 -0800
committerTony Sarajärvi <tony.sarajarvi@qt.io>2017-12-12 19:06:57 +0000
commit48d677365a1061aa973b38d7b640498830bda452 (patch)
tree71f6a8ce03168b521be7131c6b43d0c2d3a3bf3d /src/corelib
parentfefd9de52aaaae58d3c0150cbd19f0e403ba92ce (diff)
QStandardPaths: fall back to a default if PATH isn't set
Change 28666d167aa8e602c0bea25ebc4d51b55005db13 simplified QProcess::start{Process,Detached} by using findExecutable() instead of using execvp, but this introduced an unintended side effect when the PATH environment variable isn't set. It turns out that most libc have a default fallback in that situation, which we didn't apply. This commit applies the default directly to findExecutable(), which seems sensible. [ChangeLog][QtCore][QProcess] Fixed a regression that made QProcess be unable to find executables when the PATH environment variable on some Unix systems wasn't set. This behavior should not be relied upon since many systems do not have sensible fallback values for PATH. [ChangeLog][QtCore][QStandardPaths] findExecutable() will now apply the default value for the PATH environment variable (as returned by the POSIX confstr(3) function or found in <paths.h>) if the variable isn't set in the environment. Task-number: QTBUG-65076 Change-Id: I9407dcf22de6407c83b5fffd14feda6c1f509210 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io> Reviewed-by: David Faure <david.faure@kdab.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/io/qstandardpaths.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index c3d45caf0e..b3a5bd797a 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -48,6 +48,14 @@
#include <qcoreapplication.h>
#endif
+#if QT_HAS_INCLUDE(<paths.h>)
+#include <paths.h>
+#endif
+
+#ifdef Q_OS_UNIX
+#include <unistd.h>
+#endif
+
#ifndef QT_NO_STANDARDPATHS
QT_BEGIN_NAMESPACE
@@ -509,6 +517,27 @@ QString QStandardPaths::findExecutable(const QString &executableName, const QStr
QStringList searchPaths = paths;
if (paths.isEmpty()) {
QByteArray pEnv = qgetenv("PATH");
+ if (Q_UNLIKELY(pEnv.isNull())) {
+ // Get a default path. POSIX.1 does not actually require this, but
+ // most Unix libc fall back to confstr(_CS_PATH) if the PATH
+ // environment variable isn't set. Let's try to do the same.
+#if defined(_PATH_DEFPATH)
+ // BSD API.
+ pEnv = _PATH_DEFPATH;
+#elif defined(_CS_PATH)
+ // POSIX API.
+ size_t n = confstr(_CS_PATH, nullptr, 0);
+ if (n) {
+ pEnv.resize(n);
+ // size()+1 is ok because QByteArray always has an extra NUL-terminator
+ confstr(_CS_PATH, pEnv.data(), pEnv.size() + 1);
+ }
+#else
+ // Windows SDK's execvpe() does not have a fallback, so we won't
+ // apply one either.
+#endif
+ }
+
// Remove trailing slashes, which occur on Windows.
const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(QDir::listSeparator(), QString::SkipEmptyParts);
searchPaths.reserve(rawPaths.size());