diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2017-12-09 22:18:02 -0800 |
---|---|---|
committer | Tony Sarajärvi <tony.sarajarvi@qt.io> | 2017-12-12 19:06:57 +0000 |
commit | 48d677365a1061aa973b38d7b640498830bda452 (patch) | |
tree | 71f6a8ce03168b521be7131c6b43d0c2d3a3bf3d | |
parent | fefd9de52aaaae58d3c0150cbd19f0e403ba92ce (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>
-rw-r--r-- | src/corelib/io/qstandardpaths.cpp | 29 |
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()); |