Commit 29b79144 authored by Ivan Donchevskii's avatar Ivan Donchevskii

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: default avatarDavid Schulz <david.schulz@qt.io>
parent 010fb417
......@@ -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()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment