summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/Windows/Path.inc
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2017-12-05 16:40:56 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2017-12-05 16:40:56 +0000
commit20569e96e9403780e1229f31c48add56c3fc284a (patch)
treee9a38dc09816d3fbd4f7a1caffe12cc406e81781 /llvm/lib/Support/Windows/Path.inc
parent3f7eb40cdbd4db4ea88b3651670c062b61e5cf25 (diff)
downloadbcm5719-llvm-20569e96e9403780e1229f31c48add56c3fc284a.tar.gz
bcm5719-llvm-20569e96e9403780e1229f31c48add56c3fc284a.zip
Delete temp file if rename fails.
Without this when lld failed to replace the output file it would leave the temporary behind. The problem is that the existing logic is - cancel the delete flag - rename We have to cancel first to avoid renaming and then crashing and deleting the old version. What is missing then is deleting the temporary file if the rename fails. This can be an issue on both unix and windows, but I am not sure how to cause the rename to fail reliably on unix. I think it can be done on ZFS since it has an ACL system similar to what windows uses, but adding support for checking that in llvm-lit is probably not worth it. llvm-svn: 319786
Diffstat (limited to 'llvm/lib/Support/Windows/Path.inc')
-rw-r--r--llvm/lib/Support/Windows/Path.inc22
1 files changed, 17 insertions, 5 deletions
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index f5b1c0ffe69..f81790b17df 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -391,6 +391,20 @@ std::error_code is_local(int FD, bool &Result) {
return is_local_internal(FinalPath, Result);
}
+static std::error_code setDeleteDisposition(HANDLE Handle, bool Delete) {
+ FILE_DISPOSITION_INFO Disposition;
+ Disposition.DeleteFile = Delete;
+ if (!SetFileInformationByHandle(Handle, FileDispositionInfo, &Disposition,
+ sizeof(Disposition)))
+ return mapWindowsError(::GetLastError());
+ return std::error_code();
+}
+
+static std::error_code removeFD(int FD) {
+ HANDLE Handle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
+ return setDeleteDisposition(Handle, true);
+}
+
/// In order to handle temporary files we want the following properties
///
/// * The temporary file is deleted on crashes
@@ -425,11 +439,9 @@ static std::error_code cancelDeleteOnClose(int &FD) {
if (close(FD))
return mapWindowsError(::GetLastError());
- FILE_DISPOSITION_INFO Disposition;
- Disposition.DeleteFile = false;
- if (!SetFileInformationByHandle(NewHandle, FileDispositionInfo, &Disposition,
- sizeof(Disposition)))
- return mapWindowsError(::GetLastError());
+ if (std::error_code EC = setDeleteDisposition(NewHandle, false))
+ return EC;
+
FD = ::_open_osfhandle(intptr_t(NewHandle), 0);
if (FD == -1) {
::CloseHandle(NewHandle);
OpenPOWER on IntegriCloud