diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2017-10-10 19:39:46 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2017-10-10 19:39:46 +0000 |
commit | 0f9e8898816020044082065b687bb730789ca918 (patch) | |
tree | 9b866401de8cec89e9a589ff97164bed4f66b23b /llvm/lib/Support/Windows | |
parent | afd049b6a4bf59228e1f79bffb8a06199d1444a7 (diff) | |
download | bcm5719-llvm-0f9e8898816020044082065b687bb730789ca918.tar.gz bcm5719-llvm-0f9e8898816020044082065b687bb730789ca918.zip |
Support: On Windows, use CreateFileW to delete files in sys::fs::remove().
This saves a call to stat().
Differential Revision: https://reviews.llvm.org/D38715
llvm-svn: 315351
Diffstat (limited to 'llvm/lib/Support/Windows')
-rw-r--r-- | llvm/lib/Support/Windows/Path.inc | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index 045734c3694..a81cd58cf4b 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -259,29 +259,32 @@ std::error_code create_hard_link(const Twine &to, const Twine &from) { std::error_code remove(const Twine &path, bool IgnoreNonExisting) { SmallVector<wchar_t, 128> path_utf16; - file_status ST; - if (std::error_code EC = status(path, ST)) { - if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting) - return EC; - return std::error_code(); - } - if (std::error_code ec = widenPath(path, path_utf16)) return ec; - if (ST.type() == file_type::directory_file) { - if (!::RemoveDirectoryW(c_str(path_utf16))) { - std::error_code EC = mapWindowsError(::GetLastError()); - if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting) - return EC; - } - return std::error_code(); - } - if (!::DeleteFileW(c_str(path_utf16))) { + // We don't know whether this is a file or a directory, and remove() can + // accept both. The usual way to delete a file or directory is to use one of + // the DeleteFile or RemoveDirectory functions, but that requires you to know + // which one it is. We could stat() the file to determine that, but that would + // cost us additional system calls, which can be slow in a directory + // containing a large number of files. So instead we call CreateFile directly. + // The important part is the FILE_FLAG_DELETE_ON_CLOSE flag, which causes the + // file to be deleted once it is closed. We also use the flags + // FILE_FLAG_BACKUP_SEMANTICS (which allows us to open directories), and + // FILE_FLAG_OPEN_REPARSE_POINT (don't follow symlinks). + ScopedFileHandle h(::CreateFileW( + c_str(path_utf16), DELETE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS | + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_DELETE_ON_CLOSE, + NULL)); + if (!h) { std::error_code EC = mapWindowsError(::GetLastError()); if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting) return EC; } + return std::error_code(); } |