QStandardPaths: warn if $XDG_RUNTIME_DIR doesn't exist
If the environment variable is set, but points to a non-existing directory, the user would get a warning about chmod failing. Better be clear and warn about the fact that the directory itself doesn't exist. Also warn if $XDG_RUNTIME_DIR points to a file rather than a directory. Task-number: QTBUG-48771 Change-Id: If84e72d768528ea4b80260afbbc18709b7b738a8 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
This commit is contained in:
parent
4d9e06fa53
commit
5f03b48cb3
@ -113,21 +113,33 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
|||||||
{
|
{
|
||||||
const uid_t myUid = geteuid();
|
const uid_t myUid = geteuid();
|
||||||
// http://standards.freedesktop.org/basedir-spec/latest/
|
// http://standards.freedesktop.org/basedir-spec/latest/
|
||||||
|
QFileInfo fileInfo;
|
||||||
QString xdgRuntimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
|
QString xdgRuntimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
|
||||||
if (xdgRuntimeDir.isEmpty()) {
|
if (xdgRuntimeDir.isEmpty()) {
|
||||||
const QString userName = QFileSystemEngine::resolveUserName(myUid);
|
const QString userName = QFileSystemEngine::resolveUserName(myUid);
|
||||||
xdgRuntimeDir = QDir::tempPath() + QLatin1String("/runtime-") + userName;
|
xdgRuntimeDir = QDir::tempPath() + QLatin1String("/runtime-") + userName;
|
||||||
QDir dir(xdgRuntimeDir);
|
fileInfo.setFile(xdgRuntimeDir);
|
||||||
if (!dir.exists()) {
|
if (!fileInfo.isDir()) {
|
||||||
if (!QDir().mkdir(xdgRuntimeDir)) {
|
if (!QDir().mkdir(xdgRuntimeDir)) {
|
||||||
qWarning("QStandardPaths: error creating runtime directory %s: %s", qPrintable(xdgRuntimeDir), qPrintable(qt_error_string(errno)));
|
qWarning("QStandardPaths: error creating runtime directory %s: %s", qPrintable(xdgRuntimeDir), qPrintable(qt_error_string(errno)));
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qWarning("QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '%s'", qPrintable(xdgRuntimeDir));
|
qWarning("QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '%s'", qPrintable(xdgRuntimeDir));
|
||||||
|
} else {
|
||||||
|
fileInfo.setFile(xdgRuntimeDir);
|
||||||
|
if (!fileInfo.exists()) {
|
||||||
|
qWarning("QStandardPaths: XDG_RUNTIME_DIR points to non-existing path '%s', "
|
||||||
|
"please create it with 0700 permissions.", qPrintable(xdgRuntimeDir));
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
if (!fileInfo.isDir()) {
|
||||||
|
qWarning("QStandardPaths: XDG_RUNTIME_DIR points to '%s' which is not a directory",
|
||||||
|
qPrintable(xdgRuntimeDir));
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// "The directory MUST be owned by the user"
|
// "The directory MUST be owned by the user"
|
||||||
QFileInfo fileInfo(xdgRuntimeDir);
|
|
||||||
if (fileInfo.ownerId() != myUid) {
|
if (fileInfo.ownerId() != myUid) {
|
||||||
qWarning("QStandardPaths: wrong ownership on runtime directory %s, %d instead of %d", qPrintable(xdgRuntimeDir),
|
qWarning("QStandardPaths: wrong ownership on runtime directory %s, %d instead of %d", qPrintable(xdgRuntimeDir),
|
||||||
fileInfo.ownerId(), myUid);
|
fileInfo.ownerId(), myUid);
|
||||||
@ -135,14 +147,16 @@ QString QStandardPaths::writableLocation(StandardLocation type)
|
|||||||
}
|
}
|
||||||
// "and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700."
|
// "and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700."
|
||||||
// since the current user is the owner, set both xxxUser and xxxOwner
|
// since the current user is the owner, set both xxxUser and xxxOwner
|
||||||
QFile file(xdgRuntimeDir);
|
|
||||||
const QFile::Permissions wantedPerms = QFile::ReadUser | QFile::WriteUser | QFile::ExeUser
|
const QFile::Permissions wantedPerms = QFile::ReadUser | QFile::WriteUser | QFile::ExeUser
|
||||||
| QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner;
|
| QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner;
|
||||||
if (file.permissions() != wantedPerms && !file.setPermissions(wantedPerms)) {
|
if (fileInfo.permissions() != wantedPerms) {
|
||||||
|
QFile file(xdgRuntimeDir);
|
||||||
|
if (!file.setPermissions(wantedPerms)) {
|
||||||
qWarning("QStandardPaths: could not set correct permissions on runtime directory %s: %s",
|
qWarning("QStandardPaths: could not set correct permissions on runtime directory %s: %s",
|
||||||
qPrintable(xdgRuntimeDir), qPrintable(file.errorString()));
|
qPrintable(xdgRuntimeDir), qPrintable(file.errorString()));
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return xdgRuntimeDir;
|
return xdgRuntimeDir;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -464,6 +464,15 @@ void tst_qstandardpaths::testCustomRuntimeDirectory()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_XDG_PLATFORM
|
#ifdef Q_XDG_PLATFORM
|
||||||
|
struct EnvVarRestorer
|
||||||
|
{
|
||||||
|
EnvVarRestorer() : origRuntimeDir(qgetenv("XDG_RUNTIME_DIR")) {}
|
||||||
|
~EnvVarRestorer() { qputenv("XDG_RUNTIME_DIR", origRuntimeDir.constData()); }
|
||||||
|
const QByteArray origRuntimeDir;
|
||||||
|
};
|
||||||
|
EnvVarRestorer restorer;
|
||||||
|
|
||||||
|
// When $XDG_RUNTIME_DIR points to a directory with wrong ownership, QStandardPaths should warn
|
||||||
qputenv("XDG_RUNTIME_DIR", QFile::encodeName("/tmp"));
|
qputenv("XDG_RUNTIME_DIR", QFile::encodeName("/tmp"));
|
||||||
// It's very unlikely that /tmp is 0600 or that we can chmod it
|
// It's very unlikely that /tmp is 0600 or that we can chmod it
|
||||||
// The call below outputs
|
// The call below outputs
|
||||||
@ -474,6 +483,20 @@ void tst_qstandardpaths::testCustomRuntimeDirectory()
|
|||||||
qPrintable(QString::fromLatin1("QStandardPaths: wrong ownership on runtime directory /tmp, 0 instead of %1").arg(uid)));
|
qPrintable(QString::fromLatin1("QStandardPaths: wrong ownership on runtime directory /tmp, 0 instead of %1").arg(uid)));
|
||||||
const QString runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
|
const QString runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
|
||||||
QVERIFY2(runtimeDir.isEmpty(), qPrintable(runtimeDir));
|
QVERIFY2(runtimeDir.isEmpty(), qPrintable(runtimeDir));
|
||||||
|
|
||||||
|
// When $XDG_RUNTIME_DIR points to a non-existing directory, QStandardPaths should warn (QTBUG-48771)
|
||||||
|
qputenv("XDG_RUNTIME_DIR", "does_not_exist");
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "QStandardPaths: XDG_RUNTIME_DIR points to non-existing path 'does_not_exist', please create it with 0700 permissions.");
|
||||||
|
const QString nonExistingRuntimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
|
||||||
|
QVERIFY2(nonExistingRuntimeDir.isEmpty(), qPrintable(nonExistingRuntimeDir));
|
||||||
|
|
||||||
|
// When $XDG_RUNTIME_DIR points to a file, QStandardPaths should warn
|
||||||
|
const QString file = QFINDTESTDATA("tst_qstandardpaths.cpp");
|
||||||
|
QVERIFY(!file.isEmpty());
|
||||||
|
qputenv("XDG_RUNTIME_DIR", QFile::encodeName(file));
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, qPrintable(QString::fromLatin1("QStandardPaths: XDG_RUNTIME_DIR points to '%1' which is not a directory").arg(file)));
|
||||||
|
const QString noRuntimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
|
||||||
|
QVERIFY2(noRuntimeDir.isEmpty(), qPrintable(file));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user