25 #include <sys/types.h> 36 #ifndef _ERRNO_T_DEFINED 37 #define _ERRNO_T_DEFINED 42 # pragma comment(lib, "advapi32.lib") // This provides CryptAcquireContextW. 43 # pragma comment(lib, "ole32.lib") // This provides CoTaskMemFree 48 using llvm::sys::windows::UTF8ToUTF16;
49 using llvm::sys::windows::CurCPToUTF16;
50 using llvm::sys::windows::UTF16ToUTF8;
51 using llvm::sys::path::widenPath;
70 std::error_code widenPath(
const Twine &Path8,
72 const size_t MaxDirLen = MAX_PATH - 12;
84 CurPathLen = ::GetCurrentDirectoryW(0, NULL);
90 if ((Path8Str.
size() + CurPathLen) >= MaxDirLen &&
97 FullPath.append(CurPath);
109 if (
I->size() == 1 && *
I ==
".")
111 if (
I->size() == 2 && *
I ==
"..")
116 return UTF8ToUTF16(FullPath, Path16);
120 return UTF8ToUTF16(Path8Str, Path16);
147 if (UTF16ToUTF8(PathName.
data(), PathName.
size(), PathNameUTF8))
150 return std::string(PathNameUTF8.
data());
156 uint64_t FileID = (
static_cast<uint64_t
>(FileIndexHigh) << 32ULL) |
157 static_cast<uint64_t
>(FileIndexLow);
159 return UniqueID(VolumeSerialNumber, FileID);
163 ULARGE_INTEGER Avail, Total, Free;
164 if (!::GetDiskFreeSpaceExA(Path.
str().c_str(), &Avail, &Total, &Free))
166 space_info SpaceInfo;
168 (
static_cast<uint64_t
>(Total.HighPart) << 32) + Total.LowPart;
169 SpaceInfo.free = (
static_cast<uint64_t
>(Free.HighPart) << 32) + Free.LowPart;
170 SpaceInfo.available =
171 (
static_cast<uint64_t
>(Avail.HighPart) << 32) + Avail.LowPart;
175 TimePoint<> basic_file_status::getLastAccessedTime()
const {
177 Time.dwLowDateTime = LastAccessedTimeLow;
178 Time.dwHighDateTime = LastAccessedTimeHigh;
182 TimePoint<> basic_file_status::getLastModificationTime()
const {
184 Time.dwLowDateTime = LastWriteTimeLow;
185 Time.dwHighDateTime = LastWriteTimeHigh;
189 uint32_t file_status::getLinkCount()
const {
195 DWORD len = MAX_PATH;
199 len = ::GetCurrentDirectoryW(cur_path.
capacity(), cur_path.
data());
207 }
while (len > cur_path.
capacity());
212 return UTF16ToUTF8(cur_path.
begin(), cur_path.
size(), result);
218 if (std::error_code ec = widenPath(path, wide_path))
221 if (!::SetCurrentDirectoryW(wide_path.
begin()))
224 return std::error_code();
231 if (std::error_code ec = widenPath(path, path_utf16))
234 if (!::CreateDirectoryW(path_utf16.
begin(), NULL)) {
235 DWORD LastError = ::GetLastError();
236 if (LastError != ERROR_ALREADY_EXISTS || !IgnoreExisting)
240 return std::error_code();
248 if (std::error_code ec = widenPath(from, wide_from))
250 if (std::error_code ec = widenPath(to, wide_to))
253 if (!::CreateHardLinkW(wide_from.
begin(), wide_to.
begin(), NULL))
256 return std::error_code();
263 std::error_code
remove(
const Twine &path,
bool IgnoreNonExisting) {
266 if (std::error_code ec = widenPath(path, path_utf16))
280 c_str(path_utf16), DELETE,
281 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
283 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS |
284 FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_DELETE_ON_CLOSE,
292 return std::error_code();
302 ::GetVolumePathNameW(Path.
data(), VolumePath.
data(), VolumePath.
size());
307 DWORD Err = ::GetLastError();
308 if (Err != ERROR_INSUFFICIENT_BUFFER)
318 const wchar_t *
P = VolumePath.
data();
320 UINT
Type = ::GetDriveTypeW(P);
324 return std::error_code();
328 case DRIVE_REMOVABLE:
330 return std::error_code();
346 if (std::error_code ec = widenPath(P, WidePath))
348 return is_local_internal(WidePath, result);
351 static std::error_code realPathFromHandle(HANDLE
H,
353 DWORD CountChars = ::GetFinalPathNameByHandleW(
354 H, Buffer.
begin(), Buffer.
capacity() - 1, FILE_NAME_NORMALIZED);
355 if (CountChars > Buffer.
capacity()) {
359 CountChars = ::GetFinalPathNameByHandleW(
360 H, Buffer.
data(), Buffer.
capacity() - 1, FILE_NAME_NORMALIZED);
365 return std::error_code();
368 static std::error_code realPathFromHandle(HANDLE H,
372 if (std::error_code EC = realPathFromHandle(H, Buffer))
375 const wchar_t *
Data = Buffer.
data();
377 if (CountChars >= 4) {
378 if (0 == ::
memcmp(Data, L
"\\\\?\\", 8)) {
385 return UTF16ToUTF8(Data, CountChars, RealPath);
388 std::error_code
is_local(
int FD,
bool &Result) {
390 HANDLE Handle =
reinterpret_cast<HANDLE
>(_get_osfhandle(FD));
392 if (std::error_code EC = realPathFromHandle(Handle, FinalPath))
395 return is_local_internal(FinalPath, Result);
398 static std::error_code setDeleteDisposition(HANDLE Handle,
bool Delete) {
399 FILE_DISPOSITION_INFO Disposition;
400 Disposition.DeleteFile = Delete;
401 if (!SetFileInformationByHandle(Handle, FileDispositionInfo, &Disposition,
402 sizeof(Disposition)))
404 return std::error_code();
407 static std::error_code rename_internal(HANDLE FromHandle,
const Twine &To,
408 bool ReplaceIfExists) {
410 if (
auto EC = widenPath(To, ToWide))
413 std::vector<char> RenameInfoBuf(
sizeof(FILE_RENAME_INFO) -
sizeof(
wchar_t) +
414 (ToWide.
size() *
sizeof(wchar_t)));
415 FILE_RENAME_INFO &RenameInfo =
416 *
reinterpret_cast<FILE_RENAME_INFO *
>(RenameInfoBuf.data());
417 RenameInfo.ReplaceIfExists = ReplaceIfExists;
418 RenameInfo.RootDirectory = 0;
419 RenameInfo.FileNameLength = ToWide.
size() *
sizeof(wchar_t);
422 SetLastError(ERROR_SUCCESS);
423 if (!SetFileInformationByHandle(FromHandle, FileRenameInfo, &RenameInfo,
424 RenameInfoBuf.size())) {
425 unsigned Error = GetLastError();
426 if (Error == ERROR_SUCCESS)
427 Error = ERROR_CALL_NOT_IMPLEMENTED;
431 return std::error_code();
434 static std::error_code rename_handle(HANDLE FromHandle,
const Twine &To) {
436 if (std::error_code EC = widenPath(To, WideTo))
442 for (
unsigned Retry = 0; Retry != 200; ++Retry) {
443 auto EC = rename_internal(FromHandle, To,
true);
446 std::error_code(ERROR_CALL_NOT_IMPLEMENTED, std::system_category())) {
450 if (std::error_code EC2 = realPathFromHandle(FromHandle, WideFrom))
452 if (::MoveFileExW(WideFrom.
begin(), WideTo.
begin(),
453 MOVEFILE_REPLACE_EXISTING))
454 return std::error_code();
468 ::CreateFileW(WideTo.
begin(), GENERIC_READ | DELETE,
469 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
471 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL));
482 BY_HANDLE_FILE_INFORMATION FI;
483 if (!GetFileInformationByHandle(ToHandle, &FI))
487 for (
unsigned UniqueId = 0; UniqueId != 200; ++UniqueId) {
488 std::string TmpFilename = (To +
".tmp" +
utostr(UniqueId)).str();
489 if (
auto EC = rename_internal(ToHandle, TmpFilename,
false)) {
497 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
498 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
505 BY_HANDLE_FILE_INFORMATION FI2;
506 if (!GetFileInformationByHandle(ToHandle2, &FI2))
508 if (FI.nFileIndexHigh != FI2.nFileIndexHigh ||
509 FI.nFileIndexLow != FI2.nFileIndexLow ||
510 FI.dwVolumeSerialNumber != FI2.dwVolumeSerialNumber)
529 static std::error_code rename_fd(
int FromFD,
const Twine &To) {
530 HANDLE FromHandle =
reinterpret_cast<HANDLE
>(_get_osfhandle(FromFD));
531 return rename_handle(FromHandle, To);
537 if (std::error_code EC = widenPath(From, WideFrom))
542 for (
unsigned Retry = 0; Retry != 200; ++Retry) {
546 ::CreateFileW(WideFrom.
begin(), GENERIC_READ | DELETE,
547 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
548 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
555 return rename_handle(FromHandle, To);
558 std::error_code
resize_file(
int FD, uint64_t Size) {
559 #ifdef HAVE__CHSIZE_S 560 errno_t
error = ::_chsize_s(FD, Size);
562 errno_t error = ::_chsize(FD, Size);
564 return std::error_code(error, std::generic_category());
570 if (std::error_code EC = widenPath(Path, PathUtf16))
573 DWORD Attributes = ::GetFileAttributesW(PathUtf16.
begin());
575 if (Attributes == INVALID_FILE_ATTRIBUTES) {
577 DWORD LastError = ::GetLastError();
578 if (LastError != ERROR_FILE_NOT_FOUND &&
579 LastError != ERROR_PATH_NOT_FOUND)
584 if (Mode == AccessMode::Write && (Attributes & FILE_ATTRIBUTE_READONLY))
587 return std::error_code();
597 return A.FileIndexHigh == B.FileIndexHigh &&
598 A.FileIndexLow == B.FileIndexLow &&
599 A.FileSizeHigh == B.FileSizeHigh &&
600 A.FileSizeLow == B.FileSizeLow &&
601 A.LastAccessedTimeHigh == B.LastAccessedTimeHigh &&
602 A.LastAccessedTimeLow == B.LastAccessedTimeLow &&
603 A.LastWriteTimeHigh == B.LastWriteTimeHigh &&
604 A.LastWriteTimeLow == B.LastWriteTimeLow &&
605 A.VolumeSerialNumber == B.VolumeSerialNumber;
609 file_status fsA, fsB;
610 if (std::error_code ec =
status(A, fsA))
612 if (std::error_code ec =
status(B, fsB))
615 return std::error_code();
618 static bool isReservedName(
StringRef path) {
621 static const char *
const sReservedNames[] = {
"nul",
"con",
"prn",
"aux",
622 "com1",
"com2",
"com3",
"com4",
623 "com5",
"com6",
"com7",
"com8",
624 "com9",
"lpt1",
"lpt2",
"lpt3",
625 "lpt4",
"lpt5",
"lpt6",
"lpt7",
644 return (Attrs & FILE_ATTRIBUTE_DIRECTORY) ? file_type::directory_file
645 : file_type::regular_file;
652 static std::error_code getStatus(HANDLE FileHandle, file_status &Result) {
653 if (FileHandle == INVALID_HANDLE_VALUE)
654 goto handle_status_error;
656 switch (::GetFileType(FileHandle)) {
659 case FILE_TYPE_UNKNOWN: {
660 DWORD Err = ::GetLastError();
663 Result = file_status(file_type::type_unknown);
664 return std::error_code();
669 Result = file_status(file_type::character_file);
670 return std::error_code();
672 Result = file_status(file_type::fifo_file);
673 return std::error_code();
676 BY_HANDLE_FILE_INFORMATION
Info;
677 if (!::GetFileInformationByHandle(FileHandle, &Info))
678 goto handle_status_error;
680 Result = file_status(
681 file_type_from_attrs(Info.dwFileAttributes),
682 perms_from_attrs(Info.dwFileAttributes), Info.nNumberOfLinks,
683 Info.ftLastAccessTime.dwHighDateTime, Info.ftLastAccessTime.dwLowDateTime,
684 Info.ftLastWriteTime.dwHighDateTime, Info.ftLastWriteTime.dwLowDateTime,
685 Info.dwVolumeSerialNumber, Info.nFileSizeHigh, Info.nFileSizeLow,
686 Info.nFileIndexHigh, Info.nFileIndexLow);
687 return std::error_code();
690 DWORD LastError = ::GetLastError();
691 if (LastError == ERROR_FILE_NOT_FOUND ||
692 LastError == ERROR_PATH_NOT_FOUND)
693 Result = file_status(file_type::file_not_found);
694 else if (LastError == ERROR_SHARING_VIOLATION)
695 Result = file_status(file_type::type_unknown);
697 Result = file_status(file_type::status_error);
701 std::error_code
status(
const Twine &path, file_status &result,
bool Follow) {
706 if (isReservedName(path8)) {
707 result = file_status(file_type::character_file);
708 return std::error_code();
711 if (std::error_code ec = widenPath(path8, path_utf16))
714 DWORD attr = ::GetFileAttributesW(path_utf16.
begin());
715 if (attr == INVALID_FILE_ATTRIBUTES)
716 return getStatus(INVALID_HANDLE_VALUE, result);
718 DWORD Flags = FILE_FLAG_BACKUP_SEMANTICS;
720 if (!Follow && (attr & FILE_ATTRIBUTE_REPARSE_POINT))
721 Flags |= FILE_FLAG_OPEN_REPARSE_POINT;
724 ::CreateFileW(path_utf16.
begin(), 0,
725 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
726 NULL, OPEN_EXISTING, Flags, 0));
728 return getStatus(INVALID_HANDLE_VALUE, result);
730 return getStatus(h, result);
733 std::error_code
status(
int FD, file_status &Result) {
734 HANDLE FileHandle =
reinterpret_cast<HANDLE
>(_get_osfhandle(FD));
735 return getStatus(FileHandle, Result);
740 if (std::error_code EC = widenPath(Path, PathUTF16))
743 DWORD Attributes = ::GetFileAttributesW(PathUTF16.
begin());
744 if (Attributes == INVALID_FILE_ATTRIBUTES)
751 Attributes &= ~FILE_ATTRIBUTE_READONLY;
754 Attributes |= FILE_ATTRIBUTE_NORMAL;
757 Attributes |= FILE_ATTRIBUTE_READONLY;
760 Attributes &= ~FILE_ATTRIBUTE_NORMAL;
763 if (!::SetFileAttributesW(PathUTF16.
begin(), Attributes))
766 return std::error_code();
770 TimePoint<> ModificationTime) {
772 FILETIME ModifyFT =
toFILETIME(ModificationTime);
773 HANDLE FileHandle =
reinterpret_cast<HANDLE
>(_get_osfhandle(FD));
774 if (!SetFileTime(FileHandle, NULL, &AccessFT, &ModifyFT))
776 return std::error_code();
782 HANDLE OrigFileHandle =
reinterpret_cast<HANDLE
>(_get_osfhandle(FD));
783 if (OrigFileHandle == INVALID_HANDLE_VALUE)
788 case readonly: flprotect = PAGE_READONLY;
break;
789 case readwrite: flprotect = PAGE_READWRITE;
break;
790 case priv: flprotect = PAGE_WRITECOPY;
break;
793 HANDLE FileMappingHandle =
794 ::CreateFileMappingW(OrigFileHandle, 0, flprotect,
798 if (FileMappingHandle == NULL) {
803 DWORD dwDesiredAccess;
805 case readonly: dwDesiredAccess = FILE_MAP_READ;
break;
806 case readwrite: dwDesiredAccess = FILE_MAP_WRITE;
break;
807 case priv: dwDesiredAccess = FILE_MAP_COPY;
break;
809 Mapping = ::MapViewOfFile(FileMappingHandle,
814 if (Mapping == NULL) {
816 ::CloseHandle(FileMappingHandle);
821 MEMORY_BASIC_INFORMATION mbi;
822 SIZE_T Result = VirtualQuery(Mapping, &mbi,
sizeof(mbi));
825 ::UnmapViewOfFile(Mapping);
826 ::CloseHandle(FileMappingHandle);
829 Size = mbi.RegionSize;
837 ::CloseHandle(FileMappingHandle);
838 if (!::DuplicateHandle(::GetCurrentProcess(), OrigFileHandle,
839 ::GetCurrentProcess(), &FileHandle, 0, 0,
840 DUPLICATE_SAME_ACCESS)) {
842 ::UnmapViewOfFile(Mapping);
846 return std::error_code();
849 mapped_file_region::mapped_file_region(
int fd, mapmode
mode,
size_t length,
850 uint64_t offset, std::error_code &ec)
851 : Size(length), Mapping() {
852 ec =
init(fd, offset, mode);
857 static bool hasFlushBufferKernelBug() {
863 static const char PEMagic[] = {
'P',
'E',
'\0',
'\0'};
873 mapped_file_region::~mapped_file_region() {
878 ::UnmapViewOfFile(Mapping);
880 if (Mode == mapmode::readwrite && Exe && hasFlushBufferKernelBug()) {
888 ::FlushFileBuffers(FileHandle);
891 ::CloseHandle(FileHandle);
896 assert(Mapping &&
"Mapping failed but used anyway!");
900 char *mapped_file_region::data()
const {
901 assert(Mapping &&
"Mapping failed but used anyway!");
902 return reinterpret_cast<char*
>(Mapping);
905 const char *mapped_file_region::const_data()
const {
906 assert(Mapping &&
"Mapping failed but used anyway!");
907 return reinterpret_cast<const char*
>(Mapping);
910 int mapped_file_region::alignment() {
912 ::GetSystemInfo(&SysInfo);
913 return SysInfo.dwAllocationGranularity;
916 static basic_file_status status_from_find_data(WIN32_FIND_DATAW *FindData) {
917 return basic_file_status(file_type_from_attrs(FindData->dwFileAttributes),
918 perms_from_attrs(FindData->dwFileAttributes),
919 FindData->ftLastAccessTime.dwHighDateTime,
920 FindData->ftLastAccessTime.dwLowDateTime,
921 FindData->ftLastWriteTime.dwHighDateTime,
922 FindData->ftLastWriteTime.dwLowDateTime,
923 FindData->nFileSizeHigh, FindData->nFileSizeLow);
928 bool FollowSymlinks) {
931 if (std::error_code EC = widenPath(Path, PathUTF16))
935 if (PathUTF16.
size() > 0 &&
937 PathUTF16[Path.
size() - 1] != L
':') {
945 WIN32_FIND_DATAW FirstFind;
947 c_str(PathUTF16), FindExInfoBasic, &FirstFind, FindExSearchNameMatch,
948 NULL, FIND_FIRST_EX_LARGE_FETCH));
952 size_t FilenameLen = ::wcslen(FirstFind.cFileName);
953 while ((FilenameLen == 1 && FirstFind.cFileName[0] == L
'.') ||
954 (FilenameLen == 2 && FirstFind.cFileName[0] == L
'.' &&
955 FirstFind.cFileName[1] == L
'.'))
956 if (!::FindNextFileW(FindHandle, &FirstFind)) {
957 DWORD LastError = ::GetLastError();
959 if (LastError == ERROR_NO_MORE_FILES)
963 FilenameLen = ::wcslen(FirstFind.cFileName);
967 if (std::error_code EC =
968 UTF16ToUTF8(FirstFind.cFileName, ::wcslen(FirstFind.cFileName),
969 DirectoryEntryNameUTF8))
972 IT.IterationHandle =
intptr_t(FindHandle.take());
974 path::append(DirectoryEntryPath, DirectoryEntryNameUTF8);
976 directory_entry(DirectoryEntryPath, FollowSymlinks,
977 file_type_from_attrs(FirstFind.dwFileAttributes),
978 status_from_find_data(&FirstFind));
980 return std::error_code();
984 if (IT.IterationHandle != 0)
987 IT.IterationHandle = 0;
988 IT.CurrentEntry = directory_entry();
989 return std::error_code();
993 WIN32_FIND_DATAW FindData;
994 if (!::FindNextFileW(HANDLE(IT.IterationHandle), &FindData)) {
995 DWORD LastError = ::GetLastError();
997 if (LastError == ERROR_NO_MORE_FILES)
1002 size_t FilenameLen = ::wcslen(FindData.cFileName);
1003 if ((FilenameLen == 1 && FindData.cFileName[0] == L
'.') ||
1004 (FilenameLen == 2 && FindData.cFileName[0] == L
'.' &&
1005 FindData.cFileName[1] == L
'.'))
1009 if (std::error_code EC =
1010 UTF16ToUTF8(FindData.cFileName, ::wcslen(FindData.cFileName),
1011 DirectoryEntryPathUTF8))
1014 IT.CurrentEntry.replace_filename(
1015 Twine(DirectoryEntryPathUTF8),
1016 file_type_from_attrs(FindData.dwFileAttributes),
1017 status_from_find_data(&FindData));
1018 return std::error_code();
1027 int CrtOpenFlags = 0;
1029 CrtOpenFlags |= _O_APPEND;
1032 CrtOpenFlags |= _O_TEXT;
1038 ResultFD = ::_open_osfhandle(
intptr_t(*H), CrtOpenFlags);
1039 if (ResultFD == -1) {
1043 return std::error_code();
1055 if (Flags & OF_Append)
1060 return CREATE_ALWAYS;
1066 return OPEN_EXISTING;
1074 Result |= GENERIC_READ;
1076 Result |= GENERIC_WRITE;
1080 Result |= FILE_WRITE_ATTRIBUTES;
1084 static std::error_code openNativeFileInternal(
const Twine &
Name,
1087 bool Inherit =
false) {
1089 if (std::error_code EC = widenPath(Name, PathUTF16))
1092 SECURITY_ATTRIBUTES SA;
1093 SA.nLength =
sizeof(SA);
1094 SA.lpSecurityDescriptor =
nullptr;
1095 SA.bInheritHandle = Inherit;
1098 ::CreateFileW(PathUTF16.
begin(), Access,
1099 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, &SA,
1101 if (H == INVALID_HANDLE_VALUE) {
1102 DWORD LastError = ::GetLastError();
1107 if (LastError != ERROR_ACCESS_DENIED)
1114 return std::error_code();
1122 "Cannot specify both 'CreateNew' and 'Append' file creation flags!");
1124 DWORD NativeDisp = nativeDisposition(Disp, Flags);
1125 DWORD NativeAccess = nativeAccess(Access, Flags);
1127 bool Inherit =
false;
1132 std::error_code EC = openNativeFileInternal(
1133 Name, Result, NativeDisp, NativeAccess, FILE_ATTRIBUTE_NORMAL, Inherit);
1139 SYSTEMTIME SystemTime;
1140 GetSystemTime(&SystemTime);
1141 if (SystemTimeToFileTime(&SystemTime, &FileTime) == 0 ||
1142 SetFileTime(Result, NULL, &FileTime, NULL) == 0) {
1143 DWORD LastError = ::GetLastError();
1144 ::CloseHandle(Result);
1149 if (Flags & OF_Delete) {
1150 if ((EC = setDeleteDisposition(Result,
true))) {
1151 ::CloseHandle(Result);
1165 return nativeFileToFd(*Result, ResultFD, Flags);
1168 static std::error_code directoryRealPath(
const Twine &Name,
1171 std::error_code EC = openNativeFileInternal(
1172 Name, File, OPEN_EXISTING, GENERIC_READ, FILE_FLAG_BACKUP_SEMANTICS);
1176 EC = realPathFromHandle(File, RealPath);
1177 ::CloseHandle(File);
1185 return nativeFileToFd(std::move(NativeFile), ResultFD,
OF_None);
1194 if (Result && RealPath)
1195 realPathFromHandle(*Result, *RealPath);
1208 std::error_code EC = widenPath(path, Path16);
1209 if (EC && !IgnoreErrors)
1220 SHFILEOPSTRUCTW shfos = {};
1221 shfos.wFunc = FO_DELETE;
1222 shfos.pFrom = Path16.
data();
1223 shfos.fFlags = FOF_NO_UI;
1225 int result = ::SHFileOperationW(&shfos);
1226 if (result != 0 && !IgnoreErrors)
1228 return std::error_code();
1233 if (Path.
empty() || Path[0] !=
'~')
1240 if (!Expr.
empty()) {
1252 Path[0] = HomeDir[0];
1262 expandTildeExpr(dest);
1271 return std::error_code();
1276 expandTildeExpr(Storage);
1281 return directoryRealPath(path, dest);
1284 if (std::error_code EC =
1288 return std::error_code();
1294 static bool getKnownFolderPath(KNOWNFOLDERID folderId,
1296 wchar_t *path =
nullptr;
1297 if (::SHGetKnownFolderPath(folderId, KF_FLAG_CREATE,
nullptr, &path) != S_OK)
1300 bool ok = !UTF16ToUTF8(path, ::wcslen(path), result);
1301 ::CoTaskMemFree(path);
1306 return getKnownFolderPath(FOLDERID_Profile, result);
1314 Size = GetEnvironmentVariableW(Var, Buf.
data(), Buf.
capacity());
1322 return !windows::UTF16ToUTF8(Buf.
data(),
Size, Res);
1326 const wchar_t *EnvironmentVariables[] = {L
"TMP", L
"TEMP", L
"USERPROFILE"};
1327 for (
auto *Env : EnvironmentVariables) {
1328 if (getTempDirEnvVar(Env, Res))
1335 (void)ErasedOnReboot;
1342 if (getTempDirEnvVar(Result)) {
1343 assert(!Result.
empty() &&
"Unexpected empty path");
1350 const char *DefaultResult =
"C:\\Temp";
1351 Result.
append(DefaultResult, DefaultResult + strlen(DefaultResult));
1356 std::error_code CodePageToUTF16(
unsigned codepage,
1359 if (!original.
empty()) {
1360 int len = ::MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, original.
begin(),
1370 len = ::MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, original.
begin(),
1382 return std::error_code();
1387 return CodePageToUTF16(CP_UTF8, utf8, utf16);
1392 return CodePageToUTF16(CP_ACP, curcp, utf16);
1396 std::error_code UTF16ToCodePage(
unsigned codepage,
const wchar_t *utf16,
1401 int len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, converted.
begin(),
1412 len = ::WideCharToMultiByte(codepage, 0, utf16, utf16_len, converted.
data(),
1413 converted.
size(), NULL, NULL);
1424 return std::error_code();
1427 std::error_code UTF16ToUTF8(
const wchar_t *utf16,
size_t utf16_len,
1429 return UTF16ToCodePage(CP_UTF8, utf16, utf16_len, utf8);
1432 std::error_code UTF16ToCurCP(
const wchar_t *utf16,
size_t utf16_len,
1434 return UTF16ToCodePage(CP_ACP, utf16, utf16_len, curcp);
const file_t kInvalidFile
bool is_separator(char value, Style style=Style::native)
Check whether the given char is a path separator on the host OS.
const_iterator end(StringRef path)
Get end iterator over path.
bool can_execute(const Twine &Path)
Can we execute this file?
Represents either an error or a value T.
void remove_filename(SmallVectorImpl< char > &path, Style style=Style::native)
Remove the last component from path unless it is the root dir.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
bool status_known(const basic_file_status &s)
Is status available?
This class represents lattice values for constants.
std::error_code openFileForRead(const Twine &Name, int &ResultFD, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
void closeFile(file_t &F)
Close the file object.
FILETIME toFILETIME(TimePoint<> TP)
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
void push_back(const T &Elt)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
bool isTriviallyEmpty() const
Check if this twine is trivially empty; a false return value does not necessarily mean the twine is e...
std::error_code setLastAccessAndModificationTime(int FD, TimePoint<> AccessTime, TimePoint<> ModificationTime)
Set the file modification and access time.
StringRef toStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single StringRef if it can be represented as such.
std::error_code current_path(SmallVectorImpl< char > &result)
Get the current path.
bool is_directory(const basic_file_status &status)
Does status represent a directory?
Expected< file_t > openNativeFile(const Twine &Name, CreationDisposition Disp, FileAccess Access, OpenFlags Flags, unsigned Mode=0666)
Opens a file with the specified creation disposition, access mode, and flags and returns a platform-s...
Error takeError()
Take ownership of the stored error.
void reserve(size_type N)
std::error_code remove_directories(const Twine &path, bool IgnoreErrors=true)
Recursively delete a directory.
LLVM_ATTRIBUTE_ALWAYS_INLINE TimePoint< std::chrono::seconds > toTimePoint(std::time_t T)
Convert a std::time_t to a TimePoint.
CD_OpenExisting - When opening a file:
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
amode Optimize addressing mode
std::error_code directory_iterator_increment(DirIterState &)
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
void make_absolute(const Twine ¤t_directory, SmallVectorImpl< char > &path)
Make path an absolute path.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
std::error_code make_error_code(BitcodeError E)
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Tagged union holding either a T or a Error.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_until(function_ref< bool(char)> F) const
Return the longest prefix of 'this' such that no character in the prefix satisfies the given predicat...
When a child process is launched, this file should remain open in the child process.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
CD_CreateNew - When opening a file:
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
std::error_code is_local(const Twine &path, bool &result)
Is the file mounted on a local filesystem?
std::error_code create_link(const Twine &to, const Twine &from)
Create a link from from to to.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
Delete the file on close. Only makes a difference on windows.
The file should be opened in text mode on platforms that make this distinction.
Analysis containing CSE Info
std::string getMainExecutable(const char *argv0, void *MainExecAddr)
Return the path to the main executable, given the value of argv[0] from program startup and the addre...
std::error_code real_path(const Twine &path, SmallVectorImpl< char > &output, bool expand_tilde=false)
Collapse all .
initializer< Ty > init(const Ty &Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
The instances of the Type class are immutable: once they are created, they are never changed...
void expand_tilde(const Twine &path, SmallVectorImpl< char > &output)
Expands ~ expressions to the user's home directory.
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
std::error_code getUniqueID(const Twine Path, UniqueID &Result)
std::error_code mapWindowsError(unsigned EV)
std::error_code resize_file(int FD, uint64_t Size)
Resize path to size.
std::error_code create_hard_link(const Twine &to, const Twine &from)
Create a hard link from from to to, or return an error.
void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Force files Atime to be updated on access. Only makes a difference on windows.
static const char *const Magic
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
llvm::VersionTuple GetWindowsOSVersion()
Returns the Windows version as Major.Minor.0.BuildNumber.
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
std::error_code directory_iterator_construct(DirIterState &, StringRef, bool)
BlockVerifier::State From
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
The file should be opened in append mode.
Expected< file_t > openNativeFileForRead(const Twine &Name, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
std::error_code setPermissions(const Twine &Path, perms Permissions)
Set file permissions.
std::string utostr(uint64_t X, bool isNeg=false)
iterator insert(iterator I, T &&Elt)
std::error_code set_current_path(const Twine &path)
Set the current path.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::ZeroOrMore, cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate IT block based on arch"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow deprecated IT based on ARMv8"), clEnumValN(NoRestrictedIT, "arm-no-restrict-it", "Allow IT blocks based on ARMv7")))
bool has_root_path(const Twine &path, Style style=Style::native)
Has root path?
ErrorOr< space_info > disk_space(const Twine &Path)
Get disk space usage information.
bool startswith(StringRef Prefix) const
startswith - Check if this string starts with the given Prefix.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
std::error_code directory_iterator_destruct(DirIterState &)
Represents a version number in the form major[.minor[.subminor[.build]]].
pointer data()
Return a pointer to the vector's buffer, even if empty().
Merge contiguous icmps into a memcmp
file_type
An enumeration for the file system's view of the type.
LLVM_NODISCARD bool empty() const
uint32_t read32le(const void *P)
static bool Execute(ProcessInfo &PI, StringRef Program, ArrayRef< StringRef > Args, Optional< ArrayRef< StringRef >> Env, ArrayRef< Optional< StringRef >> Redirects, unsigned MemoryLimit, std::string *ErrMsg)
static void rename(GlobalValue *GV)
static const char PEMagic[]
std::error_code create_directory(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create the directory in path.
std::string str() const
Return the twine contents as a std::string.
void system_temp_directory(bool erasedOnReboot, SmallVectorImpl< char > &result)
Get the typical temporary directory for the system, e.g., "/var/tmp" or "C:/TEMP".
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool equivalent(file_status A, file_status B)
Do file_status's represent the same thing?
CD_CreateAlways - When opening a file:
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
void set_size(size_t Size)
Set the array size to N, which the current array must have enough capacity for.
Lightweight error class with error context and mandatory checking.
bool home_directory(SmallVectorImpl< char > &result)
Get the user's home directory.
std::error_code access(const Twine &Path, AccessMode Mode)
Can the file be accessed?
StringRef - Represent a constant reference to a string, i.e.
CD_OpenAlways - When opening a file:
bool exists(const basic_file_status &status)
Does file exist?
OutputIt copy(R &&Range, OutputIt Out)
std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.