summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/io/qfile.cpp56
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp5
2 files changed, 25 insertions, 36 deletions
diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp
index 263806c542d..c645e57bdb6 100644
--- a/src/corelib/io/qfile.cpp
+++ b/src/corelib/io/qfile.cpp
@@ -667,46 +667,30 @@ QFile::rename(const QString &newName)
return false;
}
- QFile out(newName);
- if (open(QIODevice::ReadOnly | QIODevice::Unbuffered)) {
- if (out.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Unbuffered)) {
- bool error = false;
- char block[4096];
- qint64 bytes;
- while ((bytes = read(block, sizeof(block))) > 0) {
- if (bytes != out.write(block, bytes)) {
- d->setError(QFile::RenameError, out.errorString());
- error = true;
- break;
- }
- }
- if (bytes == -1) {
- d->setError(QFile::RenameError, errorString());
- error = true;
- }
- if (!error) {
- if (!remove()) {
- d->setError(QFile::RenameError, tr("Cannot remove source file"));
- error = true;
- }
- }
- if (error) {
- out.remove();
- } else {
- d->fileEngine->setFileName(newName);
- setPermissions(permissions());
- unsetError();
- setFileName(newName);
- }
- close();
- return !error;
+#if QT_CONFIG(temporaryfile)
+ // copy the file to the destination first
+ if (d->copy(newName)) {
+ // succeeded, remove the original
+ if (!remove()) {
+ d->setError(QFile::RenameError, tr("Cannot remove source file: %1").arg(errorString()));
+ QFile out(newName);
+ // set it back to writable so we can delete it
+ out.setPermissions(ReadUser | WriteUser);
+ out.remove(newName);
+ return false;
}
- close();
- d->setError(QFile::RenameError,
- tr("Cannot open destination file: %1").arg(out.errorString()));
+ d->fileEngine->setFileName(newName);
+ unsetError();
+ setFileName(newName);
+ return true;
} else {
+ // change the error type but keep the string
d->setError(QFile::RenameError, errorString());
}
+#else
+ // copy the error from the engine rename() above
+ d->setError(QFile::RenameError, d->fileEngine->errorString());
+#endif
}
return false;
}
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
index 306dda14690..184853b28d7 100644
--- a/tests/auto/corelib/io/qfile/tst_qfile.cpp
+++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp
@@ -3026,6 +3026,11 @@ void tst_QFile::renameFallback()
QFile::remove("file-rename-destination.txt");
QVERIFY(!file.rename("file-rename-destination.txt"));
+#ifdef Q_OS_WIN
+ // wait for the file to disappear
+ QTRY_VERIFY_WITH_TIMEOUT(!QFile::exists("file-rename-destination.txt"),
+ std::chrono::seconds(1));
+#endif
QVERIFY(!QFile::exists("file-rename-destination.txt"));
QVERIFY(!file.isOpen());
}