diff options
Diffstat (limited to 'llvm/lib/Support/Windows')
-rw-r--r-- | llvm/lib/Support/Windows/Path.inc | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index d8a14b41cb2..f8a75a21e48 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -530,13 +530,15 @@ static std::error_code getStatus(HANDLE FileHandle, file_status &Result) { 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); + 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(); } @@ -589,6 +591,37 @@ std::error_code status(int FD, file_status &Result) { 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)); |