summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2015-07-14 09:29:58 +0200
committerFriedemann Kleint <Friedemann.Kleint@theqtcompany.com>2015-07-17 11:06:28 +0000
commit26bcc0565f49c731a4f288f93f04056ca20136a5 (patch)
tree72081d0d8ed73f536a249adca5a92d55be6b982d
parentd6553d2cd8a2bd84520363ee0c2b9c5c803b5543 (diff)
QDir::removeRecursively(): Retry file deletion with write permission set.
On Windows, having read-only files in a directory can cause removal to fail. When file deletion fails, check on the permissions, set write permissions and retry. Split apart code paths by OS in tst_QDir::removeRecursivelyFailure(); deletion of the read-only directory on UNIX should still fail. Change-Id: I36e54be5229a7b552e90fd5f42722b868fa0b6ee Reviewed-by: David Faure <david.faure@kdab.com>
-rw-r--r--src/corelib/io/qdir.cpp16
-rw-r--r--tests/auto/corelib/io/qdir/tst_qdir.cpp15
-rw-r--r--tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp2
3 files changed, 22 insertions, 11 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 6687ff846c..f6e132708e 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -1503,11 +1503,19 @@ bool QDir::removeRecursively()
while (di.hasNext()) {
di.next();
const QFileInfo& fi = di.fileInfo();
+ const QString &filePath = di.filePath();
bool ok;
- if (fi.isDir() && !fi.isSymLink())
- ok = QDir(di.filePath()).removeRecursively(); // recursive
- else
- ok = QFile::remove(di.filePath());
+ if (fi.isDir() && !fi.isSymLink()) {
+ ok = QDir(filePath).removeRecursively(); // recursive
+ } else {
+ ok = QFile::remove(filePath);
+ if (!ok) { // Read-only files prevent directory deletion on Windows, retry with Write permission.
+ const QFile::Permissions permissions = QFile::permissions(filePath);
+ if (!(permissions & QFile::WriteUser))
+ ok = QFile::setPermissions(filePath, permissions | QFile::WriteUser)
+ && QFile::remove(filePath);
+ }
+ }
if (!ok)
success = false;
}
diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp
index 45289df398..72d036c2ae 100644
--- a/tests/auto/corelib/io/qdir/tst_qdir.cpp
+++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp
@@ -470,21 +470,22 @@ void tst_QDir::removeRecursivelyFailure()
#ifdef Q_OS_UNIX
QFile dirAsFile(path); // yay, I have to use QFile to change a dir's permissions...
QVERIFY(dirAsFile.setPermissions(QFile::Permissions(0))); // no permissions
-#else
- QVERIFY(file.setPermissions(QFile::ReadOwner));
-#endif
+
QVERIFY(!QDir().rmdir(path));
QDir dir(path);
QVERIFY(!dir.removeRecursively()); // didn't work
QVERIFY(dir.exists()); // still exists
-#ifdef Q_OS_UNIX
QVERIFY(dirAsFile.setPermissions(QFile::Permissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner)));
-#else
- QVERIFY(file.setPermissions(QFile::ReadOwner | QFile::WriteOwner));
-#endif
QVERIFY(dir.removeRecursively());
QVERIFY(!dir.exists());
+#else // Q_OS_UNIX
+ QVERIFY(file.setPermissions(QFile::ReadOwner));
+ QVERIFY(!QDir().rmdir(path));
+ QDir dir(path);
+ QVERIFY(dir.removeRecursively());
+ QVERIFY(!dir.exists());
+#endif // !Q_OS_UNIX
}
void tst_QDir::removeRecursivelySymlink()
diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
index e144e32c77..3e98a369ce 100644
--- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
+++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
@@ -215,6 +215,8 @@ void tst_QTemporaryDir::autoRemove()
QFile file(dirName + "/dir1/file");
QVERIFY(file.open(QIODevice::WriteOnly));
QCOMPARE(file.write("Hello"), 5LL);
+ file.close();
+ QVERIFY(file.setPermissions(QFile::ReadUser));
}
#ifdef Q_OS_WIN
QTRY_VERIFY(!QDir(dirName).exists());