diff --git a/llvm/include/llvm/Support/FileSystem.h b/llvm/include/llvm/Support/FileSystem.h --- a/llvm/include/llvm/Support/FileSystem.h +++ b/llvm/include/llvm/Support/FileSystem.h @@ -772,7 +772,8 @@ /// The file should be opened in append mode. OF_Append = 4, - /// Delete the file on close. Only makes a difference on windows. + /// The returned handle can be used for deleting the file. Only makes a + /// difference on windows. OF_Delete = 8, /// When a child process is launched, this file should remain open in the diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp --- a/llvm/lib/Support/Path.cpp +++ b/llvm/lib/Support/Path.cpp @@ -1201,11 +1201,6 @@ } FD = -1; -#ifdef _WIN32 - // On windows closing will remove the file. - TmpName = ""; - return Error::success(); -#else // Always try to close and remove. std::error_code RemoveEC; if (!TmpName.empty()) { @@ -1215,7 +1210,6 @@ TmpName = ""; } return errorCodeToError(RemoveEC); -#endif } Error TempFile::keep(const Twine &Name) { @@ -1223,22 +1217,17 @@ Done = true; // Always try to close and rename. #ifdef _WIN32 - // If we can't cancel the delete don't rename. auto H = reinterpret_cast(_get_osfhandle(FD)); - std::error_code RenameEC = setDeleteDisposition(H, false); - if (!RenameEC) { - RenameEC = rename_handle(H, Name); - // If rename failed because it's cross-device, copy instead - if (RenameEC == - std::error_code(ERROR_NOT_SAME_DEVICE, std::system_category())) { - RenameEC = copy_file(TmpName, Name); - setDeleteDisposition(H, true); - } - } - - // If we can't rename, discard the temporary file. - if (RenameEC) - setDeleteDisposition(H, true); + std::error_code RenameEC = rename_handle(H, Name); + // If rename failed because it's cross-device, copy instead + if (RenameEC == + std::error_code(ERROR_NOT_SAME_DEVICE, std::system_category())) { + RenameEC = copy_file(TmpName, Name); + // Regardless of whether the copy succeeded or not, we remove the original. + remove(TmpName); + } else if (RenameEC) + // If we can't rename, discard the temporary file. + remove(TmpName); #else std::error_code RenameEC = fs::rename(TmpName, Name); if (RenameEC) { @@ -1248,8 +1237,8 @@ if (RenameEC) remove(TmpName); } - sys::DontRemoveFileOnSignal(TmpName); #endif + sys::DontRemoveFileOnSignal(TmpName); if (!RenameEC) TmpName = ""; @@ -1267,13 +1256,7 @@ assert(!Done); Done = true; -#ifdef _WIN32 - auto H = reinterpret_cast(_get_osfhandle(FD)); - if (std::error_code EC = setDeleteDisposition(H, false)) - return errorCodeToError(EC); -#else sys::DontRemoveFileOnSignal(TmpName); -#endif TmpName = ""; @@ -1295,14 +1278,12 @@ return errorCodeToError(EC); TempFile Ret(ResultPath, FD); -#ifndef _WIN32 if (sys::RemoveFileOnSignal(ResultPath)) { // Make sure we delete the file when RemoveFileOnSignal fails. consumeError(Ret.discard()); std::error_code EC(errc::operation_not_permitted); return errorCodeToError(EC); } -#endif return std::move(Ret); } } // namespace fs diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -401,43 +401,6 @@ return is_local_internal(FinalPath, Result); } -static std::error_code setDeleteDisposition(HANDLE Handle, bool Delete) { - // Clear the FILE_DISPOSITION_INFO flag first, before checking if it's a - // network file. On Windows 7 the function realPathFromHandle() below fails - // if the FILE_DISPOSITION_INFO flag was already set to 'DeleteFile = true' by - // a prior call. - FILE_DISPOSITION_INFO Disposition; - Disposition.DeleteFile = false; - if (!SetFileInformationByHandle(Handle, FileDispositionInfo, &Disposition, - sizeof(Disposition))) - return mapWindowsError(::GetLastError()); - if (!Delete) - return std::error_code(); - - // Check if the file is on a network (non-local) drive. If so, don't - // continue when DeleteFile is true, since it prevents opening the file for - // writes. Note -- this will leak temporary files on disk, but only when the - // target file is on a network drive. - SmallVector FinalPath; - if (std::error_code EC = realPathFromHandle(Handle, FinalPath)) - return EC; - - bool IsLocal; - if (std::error_code EC = is_local_internal(FinalPath, IsLocal)) - return EC; - - if (!IsLocal) - return std::error_code(); - - // The file is on a local drive, we can safely set FILE_DISPOSITION_INFO's - // flag. - Disposition.DeleteFile = true; - if (!SetFileInformationByHandle(Handle, FileDispositionInfo, &Disposition, - sizeof(Disposition))) - return mapWindowsError(::GetLastError()); - return std::error_code(); -} - static std::error_code rename_internal(HANDLE FromHandle, const Twine &To, bool ReplaceIfExists) { SmallVector ToWide; @@ -1183,12 +1146,6 @@ } } - if (Flags & OF_Delete) { - if ((EC = setDeleteDisposition(Result, true))) { - ::CloseHandle(Result); - return errorCodeToError(EC); - } - } return Result; }