diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2023-09-20 18:49:59 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2023-10-17 19:08:24 -0700 |
commit | 1c5575f194656e7b4392f2b18669010a39f5b274 (patch) | |
tree | 4849a88b6f3cce7acdb9d674fbb32ad1c31ddc13 /src/corelib/io/qfilesystemengine_unix.cpp | |
parent | ba0b4a1dc83a33238fd33fb6997d95483e7ff5f6 (diff) |
moveToTrash/Unix: trust freeDesktopTrashLocation() to find the directory
Make it receive the QSystemError so it can set the error condition
properly in case the suitable location for this input file can't be
found. This also includes the case when the input file does not exist in
the first place, which I moved into the function because upcoming
commits will imply this check anyway.
Change-Id: I9d43e5b91eb142d6945cfffd1786c6e59d3b0204
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/corelib/io/qfilesystemengine_unix.cpp')
-rw-r--r-- | src/corelib/io/qfilesystemengine_unix.cpp | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index c67cfdb966..950939597a 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -1194,9 +1194,9 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &, QFileSystemEnt Implementing as per https://specifications.freedesktop.org/trash-spec/trashspec-1.0.html */ -static QString freeDesktopTrashLocation(const QString &sourcePath) +static QString freeDesktopTrashLocation(const QFileSystemEntry &source, QSystemError &error) { - auto makeTrashDir = [](const QDir &topDir, const QString &trashDir = QString()) { + auto makeTrashDir = [](const QDir &topDir, const QString &trashDir, QSystemError &error) { auto ownerPerms = QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner; @@ -1205,13 +1205,22 @@ static QString freeDesktopTrashLocation(const QString &sourcePath) bool created = QFileSystemEngine::createDirectory(QFileSystemEntry(targetDir), false, ownerPerms); if (created) return targetDir; + error = QSystemError(errno, QSystemError::StandardLibraryError); + // maybe it already exists and is a directory if (QFileInfo(targetDir).isDir()) return targetDir; return QString(); }; + if (QFileSystemMetaData md; !QFileSystemEngine::fillMetaData(source, md, QFileSystemMetaData::ExistsAttribute) + || !md.exists()) { + error = QSystemError(ENOENT, QSystemError::StandardLibraryError); + return QString(); + } + QString trash; + const QString sourcePath = source.filePath(); const QStorageInfo sourceStorage(sourcePath); const QStorageInfo homeStorage(QDir::home()); // We support trashing of files outside the users home partition @@ -1238,10 +1247,12 @@ static QString freeDesktopTrashLocation(const QString &sourcePath) qCritical("Warning: '%s' is a symlink to '%s'", dotTrashDir.nativeFilePath().constData(), qt_readlink(dotTrashDir.nativeFilePath()).constData()); + error = QSystemError(ELOOP, QSystemError::StandardLibraryError); } else if ((st.st_mode & S_ISVTX) == 0) { // we SHOULD report the failed check to the administrator qCritical("Warning: '%s' doesn't have sticky bit set!", dotTrashDir.nativeFilePath().constData()); + error = QSystemError(EPERM, QSystemError::StandardLibraryError); } else if (S_ISDIR(st.st_mode)) { /* "If the directory exists and passes the checks, a subdirectory of the @@ -1252,7 +1263,7 @@ static QString freeDesktopTrashLocation(const QString &sourcePath) the implementation MUST immediately create it, without any warnings or delays for the user." */ - trash = makeTrashDir(dotTrashDir.filePath(), userID); + trash = makeTrashDir(dotTrashDir.filePath(), userID, error); } } /* @@ -1264,7 +1275,7 @@ static QString freeDesktopTrashLocation(const QString &sourcePath) */ if (trash.isEmpty()) { const QString userTrashDir = dotTrash + u'-' + userID; - trash = makeTrashDir(QDir(sourceStorage.rootPath() + userTrashDir)); + trash = makeTrashDir(QDir(sourceStorage.rootPath() + userTrashDir), QString(), error); } } /* @@ -1279,8 +1290,8 @@ static QString freeDesktopTrashLocation(const QString &sourcePath) */ if (trash.isEmpty()) { QDir topDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); - trash = makeTrashDir(topDir, "Trash"_L1); - if (!QFileInfo(trash).isDir()) { + trash = makeTrashDir(topDir, "Trash"_L1, error); + if (trash.isEmpty()) { qWarning("Unable to establish trash directory in %s", topDir.path().toLocal8Bit().constData()); } @@ -1293,11 +1304,6 @@ static QString freeDesktopTrashLocation(const QString &sourcePath) bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source, QFileSystemEntry &newLocation, QSystemError &error) { - const QFileInfo sourceInfo(source.filePath()); - if (!sourceInfo.exists()) { - error = QSystemError(ENOENT, QSystemError::StandardLibraryError); - return false; - } const QFileSystemEntry sourcePath = [&] { if (QString path = source.filePath(); path.size() > 1 && path.endsWith(u'/')) { path.chop(1); @@ -1305,10 +1311,10 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source, } return absoluteName(source); }(); - - QDir trashDir(freeDesktopTrashLocation(sourcePath.filePath())); - if (!trashDir.exists()) + QString trashPath = freeDesktopTrashLocation(sourcePath, error); + if (trashPath.isEmpty()) return false; + QDir trashDir(trashPath); /* "A trash directory contains two subdirectories, named info and files." */ |