summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/Windows
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2017-10-10 19:39:46 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2017-10-10 19:39:46 +0000
commit0f9e8898816020044082065b687bb730789ca918 (patch)
tree9b866401de8cec89e9a589ff97164bed4f66b23b /llvm/lib/Support/Windows
parentafd049b6a4bf59228e1f79bffb8a06199d1444a7 (diff)
downloadbcm5719-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.inc35
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();
}
OpenPOWER on IntegriCloud