diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2023-09-20 22:51:45 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2023-10-17 19:08:25 -0700 |
commit | 77c661b275dbc66798b2ac01eadcbb65c6bdaa88 (patch) | |
tree | 4bcdd2afb80f5dda7a56e85f321807adf56f7c36 /tests/auto/corelib/io/qfile/tst_qfile.cpp | |
parent | 6359e8b8bd148786b8c8b92dcde85deb45b016d3 (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.cpp | 16 |
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 } |