QStandardPaths: fall back to a default if PATH isn't set

Change 28666d167a 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>
bb10
Thiago Macieira 2017-12-09 22:18:02 -08:00 committed by Tony Sarajärvi
parent fefd9de52a
commit 48d677365a
1 changed files with 29 additions and 0 deletions

View File

@ -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());