Index: lib/Support/Windows/Path.inc =================================================================== --- lib/Support/Windows/Path.inc +++ lib/Support/Windows/Path.inc @@ -418,14 +418,13 @@ return std::error_code(); } +static std::error_code rename_handle(HANDLE Handle, const Twine &To); + std::error_code rename(const Twine &From, const Twine &To) { // Convert to utf-16. SmallVector WideFrom; - SmallVector WideTo; if (std::error_code EC = widenPath(From, WideFrom)) return EC; - if (std::error_code EC = widenPath(To, WideTo)) - return EC; ScopedFileHandle FromHandle; // Retry this a few times to defeat badly behaved file system scanners. @@ -442,6 +441,14 @@ if (!FromHandle) return mapWindowsError(GetLastError()); + return rename_handle(FromHandle, To); +} + +static std::error_code rename_handle(HANDLE FromHandle, const Twine &To) { + SmallVector WideTo; + if (std::error_code EC = widenPath(To, WideTo)) + return EC; + // We normally expect this loop to succeed after a few iterations. If it // requires more than 200 tries, it's more likely that the failures are due to // a true error, so stop trying. @@ -452,6 +459,9 @@ std::error_code(ERROR_CALL_NOT_IMPLEMENTED, std::system_category())) { // Wine doesn't support SetFileInformationByHandle in rename_internal. // Fall back to MoveFileEx. + SmallVector WideFrom; + if (std::error_code EC2 = realPathFromHandle(FromHandle, WideFrom)) + return EC2; if (::MoveFileExW(WideFrom.begin(), WideTo.begin(), MOVEFILE_REPLACE_EXISTING)) return std::error_code();