diff options
author | Michael J. Spencer <bigcheesegs@gmail.com> | 2010-12-04 00:32:40 +0000 |
---|---|---|
committer | Michael J. Spencer <bigcheesegs@gmail.com> | 2010-12-04 00:32:40 +0000 |
commit | 470ae13be812132097cf4c17a189c47def5c19a1 (patch) | |
tree | 9108ee9f6558509578add66c44202e29237cfac6 /lib/Support/Windows/PathV2.inc | |
parent | da3aaffcbb202ac492e7643fc0b191eca1931ab3 (diff) |
Support/FileSystem: Add status implementation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120870 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/Windows/PathV2.inc')
-rw-r--r-- | lib/Support/Windows/PathV2.inc | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/lib/Support/Windows/PathV2.inc b/lib/Support/Windows/PathV2.inc index a84783f96a..7d9421ac76 100644 --- a/lib/Support/Windows/PathV2.inc +++ b/lib/Support/Windows/PathV2.inc @@ -427,6 +427,54 @@ error_code file_size(const Twine &path, uint64_t &result) { return make_error_code(errc::success); } +error_code status(const Twine &path, file_status &result) { + SmallString<128> path_storage; + SmallVector<wchar_t, 128> path_utf16; + + if (error_code ec = UTF8ToUTF16(path.toStringRef(path_storage), + path_utf16)) + return ec; + + DWORD attr = ::GetFileAttributesW(path_utf16.begin()); + if (attr == INVALID_FILE_ATTRIBUTES) + goto handle_status_error; + + // Handle reparse points. + if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { + AutoHandle h( + ::CreateFileW(path_utf16.begin(), + 0, // Attributes only. + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + 0)); + if (h == INVALID_HANDLE_VALUE) + goto handle_status_error; + } + + if (attr & FILE_ATTRIBUTE_DIRECTORY) + result = file_status(file_type::directory_file); + else + result = file_status(file_type::regular_file); + + return success; + +handle_status_error: + error_code ec = windows_error(::GetLastError()); + if (ec == windows_error::file_not_found || + ec == windows_error::path_not_found) + result = file_status(file_type::file_not_found); + else if (ec == windows_error::sharing_violation) + result = file_status(file_type::type_unknown); + else { + result = file_status(file_type::status_error); + return ec; + } + + return success; +} + error_code unique_file(const Twine &model, int &result_fd, SmallVectorImpl<char> &result_path) { // Use result_path as temp storage. |