summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Support/Unix/Path.inc26
-rw-r--r--llvm/lib/Support/Windows/Path.inc79
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) {
OpenPOWER on IntegriCloud