aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/utils/savefile.cpp
diff options
context:
space:
mode:
authorIvan Donchevskii <ivan.donchevskii@qt.io>2017-11-30 15:56:24 +0100
committerIvan Donchevskii <ivan.donchevskii@qt.io>2017-12-15 13:55:41 +0000
commit29b79144297c106eface06822ddf98a84b61f9b4 (patch)
treebd3db1c2960119efd7ff66ad6f81f10d8e9c1f00 /src/libs/utils/savefile.cpp
parent010fb417003f4822075316701725e2b9a092cb1e (diff)
Utils: workaround for saving file opened by another application
...fixes file saving on Windows in specific circumstances. File deletion on Windows is quite tricky. If you simply remove the file opened by another app that shares it for deletion the file might become semi-removed. It looks like it still exists but it is in fact inaccessible for any operations until the other app frees the handle. To solve that case there is a ReplaceFile API call which carefully deals with that case. [Backstory] Oswald Buddenhagen insists that this fix is rather a workaround and we should solve file access problem in llvm. For that purpose we have QTCREATORBUG-19404 and upstream https://bugs.llvm.org/show_bug.cgi?id=35558 Task-number: QTCREATORBUG-15449 Change-Id: If37d484231b79d8e33822c795232dc31243c88c0 Reviewed-by: David Schulz <david.schulz@qt.io>
Diffstat (limited to 'src/libs/utils/savefile.cpp')
-rw-r--r--src/libs/utils/savefile.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/libs/utils/savefile.cpp b/src/libs/utils/savefile.cpp
index 55fd7ad0f72..ebe4f45b220 100644
--- a/src/libs/utils/savefile.cpp
+++ b/src/libs/utils/savefile.cpp
@@ -119,6 +119,24 @@ bool SaveFile::commit()
QString finalFileName
= FileUtils::resolveSymlinks(FileName::fromString(m_finalFileName)).toString();
+
+#ifdef Q_OS_WIN
+ // Release the file lock
+ m_tempFile.reset();
+ bool replaceResult = ReplaceFile(finalFileName.toStdWString().data(),
+ fileName().toStdWString().data(),
+ nullptr, 0, nullptr, nullptr);
+ if (!replaceResult) {
+ wchar_t messageBuffer[256];
+ size_t size = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ nullptr, GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ messageBuffer, sizeof(messageBuffer), nullptr);
+ setErrorString(QString::fromWCharArray(messageBuffer));
+ remove();
+ }
+ return replaceResult;
+#else
const QString backupName = finalFileName + '~';
// Back up current file.
@@ -148,6 +166,7 @@ bool SaveFile::commit()
QFile::remove(backupName);
return result;
+#endif
}
void SaveFile::initializeUmask()