diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2017-03-13 12:17:14 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2017-03-13 12:17:14 +0000 |
commit | f5cba91591f45baf25d097763b59915bbee81114 (patch) | |
tree | e1ff2bf0f6d56a91b9474d47726127e7438a5326 /llvm/lib/Support/Windows | |
parent | 7163ecb4294ede871a9fe5e5d27b6937d5bade7e (diff) | |
download | bcm5719-llvm-f5cba91591f45baf25d097763b59915bbee81114.tar.gz bcm5719-llvm-f5cba91591f45baf25d097763b59915bbee81114.zip |
Add support for getting file system permissions and implement sys::fs::permissions to set them.
Patch by James Henderson.
llvm-svn: 297617
Diffstat (limited to 'llvm/lib/Support/Windows')
-rw-r--r-- | llvm/lib/Support/Windows/Path.inc | 71 |
1 files changed, 52 insertions, 19 deletions
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index d8a14b41cb2..8ad1edd12e9 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -527,19 +527,21 @@ static std::error_code getStatus(HANDLE FileHandle, file_status &Result) { goto handle_status_error; { - file_type Type = (Info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - ? file_type::directory_file - : file_type::regular_file; - Result = - file_status(Type, Info.ftLastAccessTime.dwHighDateTime, - Info.ftLastAccessTime.dwLowDateTime, - Info.ftLastWriteTime.dwHighDateTime, - Info.ftLastWriteTime.dwLowDateTime, - Info.dwVolumeSerialNumber, Info.nFileSizeHigh, - Info.nFileSizeLow, Info.nFileIndexHigh, Info.nFileIndexLow); - return std::error_code(); - } - + file_type Type = (Info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ ? file_type::directory_file
+ : file_type::regular_file;
+ perms Permissions = (Info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+ ? (all_read | all_exe)
+ : all_all;
+ Result = file_status(
+ Type, Permissions, Info.ftLastAccessTime.dwHighDateTime,
+ Info.ftLastAccessTime.dwLowDateTime,
+ Info.ftLastWriteTime.dwHighDateTime, Info.ftLastWriteTime.dwLowDateTime,
+ Info.dwVolumeSerialNumber, Info.nFileSizeHigh, Info.nFileSizeLow,
+ Info.nFileIndexHigh, Info.nFileIndexLow);
+ return std::error_code();
+ }
+
handle_status_error: DWORD LastError = ::GetLastError(); if (LastError == ERROR_FILE_NOT_FOUND || @@ -586,12 +588,43 @@ std::error_code status(const Twine &path, file_status &result, bool Follow) { std::error_code status(int FD, file_status &Result) { HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD)); - return getStatus(FileHandle, Result); -} - -std::error_code setLastModificationAndAccessTime(int FD, TimePoint<> Time) { - FILETIME FT = toFILETIME(Time); - HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD)); + return getStatus(FileHandle, Result);
+}
+
+std::error_code setPermissions(const Twine &Path, perms Permissions) {
+ SmallVector<wchar_t, 128> PathUTF16;
+ if (std::error_code EC = widenPath(Path, PathUTF16))
+ return EC;
+
+ DWORD Attributes = ::GetFileAttributesW(PathUTF16.begin());
+ if (Attributes == INVALID_FILE_ATTRIBUTES)
+ return mapWindowsError(GetLastError());
+
+ // There are many Windows file attributes that are not to do with the file
+ // permissions (e.g. FILE_ATTRIBUTE_HIDDEN). We need to be careful to preserve
+ // them.
+ if (Permissions & all_write) {
+ Attributes &= ~FILE_ATTRIBUTE_READONLY;
+ if (Attributes == 0)
+ // FILE_ATTRIBUTE_NORMAL indicates no other attributes are set.
+ Attributes |= FILE_ATTRIBUTE_NORMAL;
+ }
+ else {
+ Attributes |= FILE_ATTRIBUTE_READONLY;
+ // FILE_ATTRIBUTE_NORMAL is not compatible with any other attributes, so
+ // remove it, if it is present.
+ Attributes &= ~FILE_ATTRIBUTE_NORMAL;
+ }
+
+ if (!::SetFileAttributesW(PathUTF16.begin(), Attributes))
+ return mapWindowsError(GetLastError());
+
+ return std::error_code();
+}
+
+std::error_code setLastModificationAndAccessTime(int FD, TimePoint<> Time) {
+ FILETIME FT = toFILETIME(Time);
+ HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
if (!SetFileTime(FileHandle, NULL, &FT, &FT)) return mapWindowsError(::GetLastError()); return std::error_code(); |