summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/io/qfile/tst_qfile.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2023-09-20 22:51:45 -0700
committerThiago Macieira <thiago.macieira@intel.com>2023-10-17 19:08:25 -0700
commit77c661b275dbc66798b2ac01eadcbb65c6bdaa88 (patch)
tree4bcdd2afb80f5dda7a56e85f321807adf56f7c36 /tests/auto/corelib/io/qfile/tst_qfile.cpp
parent6359e8b8bd148786b8c8b92dcde85deb45b016d3 (diff)
moveToTrash/Unix: use lower-level API to write the info file
So we can more easily get any errors from attempting to write the file. It is possible to get them with QFile, by either doing .flush() or using QIODevice::Unbuffered, but using the C API is a definite sure way. Plus, since this is QFileSystemEngine, this avoids the possibility that QFile may choose to use a different file engine than the native one, for some reason. And it reduces overhead. This allows us to more easily detect why the file creation failed and therefore stop looping if the error wasn't EEXIST. That will avoid an infinite loop in case the necessary directories exist but aren't writable. It's also moved above the renaming, such that the failure to populate the info file prevents the renaming too. Both operations can have the same likely errors, ENOSPC and EIO. The likelihood of EIO is very low, for both; but for ENOSPC it's far more likely for writing the file. Avoiding the ENOSPC error for the renaming is handled in a later commit. Change-Id: I9d43e5b91eb142d6945cfffd1786d417142ac728 Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Diffstat (limited to 'tests/auto/corelib/io/qfile/tst_qfile.cpp')
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
index 391471b15f..440fe4f48c 100644
--- a/tests/auto/corelib/io/qfile/tst_qfile.cpp
+++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp
@@ -4273,11 +4273,25 @@ void tst_QFile::moveToTrashXdgSafety()
QVERIFY(genericTrashDir.entryList(QDir::NoDotAndDotDot).isEmpty());
QFile::remove(genericTrashDir.path());
- genericTrashDir.mkpath(".");
+ genericTrashDir.mkdir(genericTrashDir.path(), QFile::ExeOwner | QFile::ReadOwner);
QTest::ignoreMessage(QtCriticalMsg, "Warning: '" + QFile::encodeName(genericTrashDir.absolutePath())
+ "' doesn't have sticky bit set!");
QVERIFY(tryTrashing());
QVERIFY(genericTrashDir.entryList(QDir::NoDotAndDotDot).isEmpty());
+
+ if (geteuid() != 0) {
+ // set the sticky bit, but make the dir unwritable; there'll be no
+ // warning and we should just fall back to the next option
+ chmod(QFile::encodeName(genericTrashDir.path()), 01555);
+ QVERIFY(tryTrashing());
+ QVERIFY(genericTrashDir.entryList(QDir::NoDotAndDotDot).isEmpty());
+
+ // ditto for our user's subdir now
+ chmod(QFile::encodeName(genericTrashDir.path()), 01755);
+ genericTrashDir.mkdir(QString::number(getuid()), QFile::ReadOwner);
+ QEXPECT_FAIL("", "Fall back not working", Continue);
+ QVERIFY(tryTrashing());
+ }
#endif
}