diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Support/Unix/Path.inc | 26 | ||||
| -rw-r--r-- | llvm/lib/Support/Windows/Path.inc | 79 |
2 files changed, 75 insertions, 30 deletions
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc index f9778321dd2..fbfbed66fbc 100644 --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc @@ -93,6 +93,9 @@ using namespace llvm; namespace llvm { namespace sys { namespace fs { + +const file_t kInvalidFile = -1; + #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ defined(__minix) || defined(__FreeBSD_kernel__) || defined(__linux__) || \ defined(__CYGWIN__) || defined(__DragonFly__) || defined(_AIX) @@ -761,6 +764,15 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD, return std::error_code(); } +Expected<file_t> openNativeFileForRead(const Twine &Name, + SmallVectorImpl<char> *RealPath) { + file_t ResultFD; + std::error_code EC = openFileForRead(Name, ResultFD, RealPath); + if (EC) + return errorCodeToError(EC); + return ResultFD; +} + std::error_code openFileForWrite(const Twine &Name, int &ResultFD, sys::fs::OpenFlags Flags, unsigned Mode) { // Verify that we don't have both "append" and "excl". @@ -798,6 +810,20 @@ std::error_code openFileForWrite(const Twine &Name, int &ResultFD, return std::error_code(); } +Expected<file_t> openNativeFileForWrite(const Twine &Name, OpenFlags Flags, + unsigned Mode) { + file_t ResultFD; + std::error_code EC = openFileForWrite(Name, ResultFD, Flags, Mode); + if (EC) + return errorCodeToError(EC); + return ResultFD; +} + +void closeFile(file_t &F) { + ::close(F); + F = kInvalidFile; +} + template <typename T> static std::error_code remove_directories_impl(const T &Entry, bool IgnoreErrors) { diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index 0d1631d6bb0..3f6aa114505 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -123,6 +123,8 @@ std::error_code widenPath(const Twine &Path8, namespace fs { +const file_t kInvalidFile = INVALID_HANDLE_VALUE; + std::string getMainExecutable(const char *argv0, void *MainExecAddr) { SmallVector<wchar_t, MAX_PATH> PathName; DWORD Size = ::GetModuleFileNameW(NULL, PathName.data(), PathName.capacity()); @@ -1051,13 +1053,32 @@ static std::error_code directoryRealPath(const Twine &Name, return EC; } +static std::error_code nativeFileToFd(Expected<HANDLE> H, int &ResultFD, + int OpenFlags) { + ResultFD = -1; + if (!H) + return errorToErrorCode(H.takeError()); + + ResultFD = ::_open_osfhandle(intptr_t(*H), OpenFlags); + if (ResultFD == -1) { + ::CloseHandle(*H); + return mapWindowsError(ERROR_INVALID_HANDLE); + } + return std::error_code(); +} + std::error_code openFileForRead(const Twine &Name, int &ResultFD, SmallVectorImpl<char> *RealPath) { - ResultFD = -1; + Expected<HANDLE> NativeFile = openNativeFileForRead(Name, RealPath); + return nativeFileToFd(std::move(NativeFile), ResultFD, 0); +} + +Expected<file_t> openNativeFileForRead(const Twine &Name, + SmallVectorImpl<char> *RealPath) { SmallVector<wchar_t, 128> PathUTF16; if (std::error_code EC = widenPath(Name, PathUTF16)) - return EC; + return errorCodeToError(EC); HANDLE H = ::CreateFileW(PathUTF16.begin(), GENERIC_READ, @@ -1070,36 +1091,42 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD, // This only runs if we failed to open the file, so there is probably // no performances issues. if (LastError != ERROR_ACCESS_DENIED) - return EC; + return errorCodeToError(EC); if (is_directory(Name)) - return make_error_code(errc::is_a_directory); - return EC; - } - - ResultFD = ::_open_osfhandle(intptr_t(H), 0); - if (ResultFD == -1) { - ::CloseHandle(H); - return mapWindowsError(ERROR_INVALID_HANDLE); + return errorCodeToError(make_error_code(errc::is_a_directory)); + return errorCodeToError(EC); } // Fetch the real name of the file, if the user asked if (RealPath) realPathFromHandle(H, *RealPath); - return std::error_code(); + return H; } std::error_code openFileForWrite(const Twine &Name, int &ResultFD, sys::fs::OpenFlags Flags, unsigned Mode) { + int OpenFlags = 0; + if (Flags & F_Append) + OpenFlags |= _O_APPEND; + + if (Flags & F_Text) + OpenFlags |= _O_TEXT; + + Expected<HANDLE> NativeFile = openNativeFileForWrite(Name, Flags, Mode); + return nativeFileToFd(std::move(NativeFile), ResultFD, OpenFlags); +} + +Expected<file_t> openNativeFileForWrite(const Twine &Name, OpenFlags Flags, + unsigned Mode) { // Verify that we don't have both "append" and "excl". assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) && "Cannot specify both 'excl' and 'append' file creation flags!"); - ResultFD = -1; SmallVector<wchar_t, 128> PathUTF16; if (std::error_code EC = widenPath(Name, PathUTF16)) - return EC; + return errorCodeToError(EC); DWORD CreationDisposition; if (Flags & F_Excl) @@ -1130,26 +1157,18 @@ std::error_code openFileForWrite(const Twine &Name, int &ResultFD, // This only runs if we failed to open the file, so there is probably // no performances issues. if (LastError != ERROR_ACCESS_DENIED) - return EC; + return errorCodeToError(EC); if (is_directory(Name)) - return make_error_code(errc::is_a_directory); - return EC; + return errorCodeToError(make_error_code(errc::is_a_directory)); + return errorCodeToError(EC); } - int OpenFlags = 0; - if (Flags & F_Append) - OpenFlags |= _O_APPEND; - - if (Flags & F_Text) - OpenFlags |= _O_TEXT; - - ResultFD = ::_open_osfhandle(intptr_t(H), OpenFlags); - if (ResultFD == -1) { - ::CloseHandle(H); - return mapWindowsError(ERROR_INVALID_HANDLE); - } + return H; +} - return std::error_code(); +void closeFile(file_t &F) { + ::CloseHandle(F); + F = kInvalidFile; } std::error_code remove_directories(const Twine &path, bool IgnoreErrors) { |

