summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support')
-rw-r--r--llvm/lib/Support/FileOutputBuffer.cpp3
-rw-r--r--llvm/lib/Support/MemoryBuffer.cpp8
-rw-r--r--llvm/lib/Support/Path.cpp15
-rw-r--r--llvm/lib/Support/TarWriter.cpp4
-rw-r--r--llvm/lib/Support/Unix/Path.inc125
-rw-r--r--llvm/lib/Support/Windows/Path.inc205
-rw-r--r--llvm/lib/Support/Windows/Program.inc2
-rw-r--r--llvm/lib/Support/raw_ostream.cpp33
8 files changed, 251 insertions, 144 deletions
diff --git a/llvm/lib/Support/FileOutputBuffer.cpp b/llvm/lib/Support/FileOutputBuffer.cpp
index cd08b61d0d6..0a771682a2c 100644
--- a/llvm/lib/Support/FileOutputBuffer.cpp
+++ b/llvm/lib/Support/FileOutputBuffer.cpp
@@ -82,9 +82,10 @@ public:
size_t getBufferSize() const override { return Buffer.size(); }
Error commit() override {
+ using namespace sys::fs;
int FD;
std::error_code EC;
- if (auto EC = openFileForWrite(FinalPath, FD, fs::F_None, Mode))
+ if (auto EC = openFileForWrite(FinalPath, FD, CD_CreateAlways, OF_None))
return errorCodeToError(EC);
raw_fd_ostream OS(FD, /*shouldClose=*/true, /*unbuffered=*/true);
OS << StringRef((const char *)Buffer.base(), Buffer.size());
diff --git a/llvm/lib/Support/MemoryBuffer.cpp b/llvm/lib/Support/MemoryBuffer.cpp
index fe04bb6fb57..d8cc853f2a8 100644
--- a/llvm/lib/Support/MemoryBuffer.cpp
+++ b/llvm/lib/Support/MemoryBuffer.cpp
@@ -244,7 +244,7 @@ static ErrorOr<std::unique_ptr<MB>>
getFileAux(const Twine &Filename, int64_t FileSize, uint64_t MapSize,
uint64_t Offset, bool RequiresNullTerminator, bool IsVolatile) {
int FD;
- std::error_code EC = sys::fs::openFileForRead(Filename, FD);
+ std::error_code EC = sys::fs::openFileForRead(Filename, FD, sys::fs::OF_None);
if (EC)
return EC;
@@ -364,8 +364,8 @@ static ErrorOr<std::unique_ptr<WriteThroughMemoryBuffer>>
getReadWriteFile(const Twine &Filename, uint64_t FileSize, uint64_t MapSize,
uint64_t Offset) {
int FD;
- std::error_code EC = sys::fs::openFileForWrite(
- Filename, FD, sys::fs::F_RW | sys::fs::F_NoTrunc);
+ std::error_code EC = sys::fs::openFileForReadWrite(
+ Filename, FD, sys::fs::CD_OpenExisting, sys::fs::OF_None);
if (EC)
return EC;
@@ -518,7 +518,7 @@ ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getSTDIN() {
ErrorOr<std::unique_ptr<MemoryBuffer>>
MemoryBuffer::getFileAsStream(const Twine &Filename) {
int FD;
- std::error_code EC = sys::fs::openFileForRead(Filename, FD);
+ std::error_code EC = sys::fs::openFileForRead(Filename, FD, sys::fs::OF_None);
if (EC)
return EC;
ErrorOr<std::unique_ptr<MemoryBuffer>> Ret =
diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp
index a592ed286fe..32c19a0515b 100644
--- a/llvm/lib/Support/Path.cpp
+++ b/llvm/lib/Support/Path.cpp
@@ -169,7 +169,7 @@ static std::error_code
createUniqueEntity(const Twine &Model, int &ResultFD,
SmallVectorImpl<char> &ResultPath, bool MakeAbsolute,
unsigned Mode, FSEntity Type,
- sys::fs::OpenFlags Flags = sys::fs::F_RW) {
+ sys::fs::OpenFlags Flags = sys::fs::OF_None) {
SmallString<128> ModelStorage;
Model.toVector(ModelStorage);
@@ -201,8 +201,8 @@ retry_random_path:
switch (Type) {
case FS_File: {
if (std::error_code EC =
- sys::fs::openFileForWrite(Twine(ResultPath.begin()), ResultFD,
- Flags | sys::fs::F_Excl, Mode)) {
+ sys::fs::openFileForReadWrite(Twine(ResultPath.begin()), ResultFD,
+ sys::fs::CD_CreateNew, Flags, Mode)) {
if (EC == errc::file_exists)
goto retry_random_path;
return EC;
@@ -929,9 +929,10 @@ std::error_code create_directories(const Twine &Path, bool IgnoreExisting,
std::error_code copy_file(const Twine &From, const Twine &To) {
int ReadFD, WriteFD;
- if (std::error_code EC = openFileForRead(From, ReadFD))
+ if (std::error_code EC = openFileForRead(From, ReadFD, OF_None))
return EC;
- if (std::error_code EC = openFileForWrite(To, WriteFD, F_None)) {
+ if (std::error_code EC =
+ openFileForWrite(To, WriteFD, CD_CreateAlways, OF_None)) {
close(ReadFD);
return EC;
}
@@ -983,7 +984,7 @@ ErrorOr<MD5::MD5Result> md5_contents(int FD) {
ErrorOr<MD5::MD5Result> md5_contents(const Twine &Path) {
int FD;
- if (auto EC = openFileForRead(Path, FD))
+ if (auto EC = openFileForRead(Path, FD, OF_None))
return EC;
auto Result = md5_contents(FD);
@@ -1180,7 +1181,7 @@ Expected<TempFile> TempFile::create(const Twine &Model, unsigned Mode) {
int FD;
SmallString<128> ResultPath;
if (std::error_code EC =
- createUniqueFile(Model, FD, ResultPath, Mode, F_Delete | F_RW))
+ createUniqueFile(Model, FD, ResultPath, Mode, OF_Delete))
return errorCodeToError(EC);
TempFile Ret(ResultPath, FD);
diff --git a/llvm/lib/Support/TarWriter.cpp b/llvm/lib/Support/TarWriter.cpp
index abc46d07657..5b4d554befe 100644
--- a/llvm/lib/Support/TarWriter.cpp
+++ b/llvm/lib/Support/TarWriter.cpp
@@ -159,8 +159,10 @@ static void writeUstarHeader(raw_fd_ostream &OS, StringRef Prefix,
// Creates a TarWriter instance and returns it.
Expected<std::unique_ptr<TarWriter>> TarWriter::create(StringRef OutputPath,
StringRef BaseDir) {
+ using namespace sys::fs;
int FD;
- if (std::error_code EC = openFileForWrite(OutputPath, FD, sys::fs::F_None))
+ if (std::error_code EC =
+ openFileForWrite(OutputPath, FD, CD_CreateAlways, OF_None))
return make_error<StringError>("cannot open " + OutputPath, EC);
return std::unique_ptr<TarWriter>(new TarWriter(FD, BaseDir));
}
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index fbfbed66fbc..59d2cb58cf0 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -722,21 +722,69 @@ static bool hasProcSelfFD() {
}
#endif
-std::error_code openFileForRead(const Twine &Name, int &ResultFD,
- SmallVectorImpl<char> *RealPath) {
- SmallString<128> Storage;
- StringRef P = Name.toNullTerminatedStringRef(Storage);
- int OpenFlags = O_RDONLY;
+static int nativeOpenFlags(CreationDisposition Disp, OpenFlags Flags,
+ FileAccess Access) {
+ int Result = 0;
+ if (Access == FA_Read)
+ Result |= O_RDONLY;
+ else if (Access == FA_Write)
+ Result |= O_WRONLY;
+ else if (Access == (FA_Read | FA_Write))
+ Result |= O_RDWR;
+
+ // This is for compatibility with old code that assumed F_Append implied
+ // would open an existing file. See Windows/Path.inc for a longer comment.
+ if (Flags & F_Append)
+ Disp = CD_OpenAlways;
+
+ if (Disp == CD_CreateNew) {
+ Result |= O_CREAT; // Create if it doesn't exist.
+ Result |= O_EXCL; // Fail if it does.
+ } else if (Disp == CD_CreateAlways) {
+ Result |= O_CREAT; // Create if it doesn't exist.
+ Result |= O_TRUNC; // Truncate if it does.
+ } else if (Disp == CD_OpenAlways) {
+ Result |= O_CREAT; // Create if it doesn't exist.
+ } else if (Disp == CD_OpenExisting) {
+ // Nothing special, just don't add O_CREAT and we get these semantics.
+ }
+
+ if (Flags & F_Append)
+ Result |= O_APPEND;
+
#ifdef O_CLOEXEC
- OpenFlags |= O_CLOEXEC;
+ Result |= O_CLOEXEC;
#endif
- if ((ResultFD = sys::RetryAfterSignal(-1, open, P.begin(), OpenFlags)) < 0)
+
+ return Result;
+}
+
+static std::error_code openFile(const Twine &Name, int &ResultFD,
+ CreationDisposition Disp, FileAccess Access,
+ OpenFlags Flags, unsigned Mode) {
+ int OpenFlags = nativeOpenFlags(Disp, Flags, Access);
+
+ SmallString<128> Storage;
+ StringRef P = Name.toNullTerminatedStringRef(Storage);
+ if ((ResultFD = sys::RetryAfterSignal(-1, open, P.begin(), OpenFlags, Mode)) <
+ 0)
return std::error_code(errno, std::generic_category());
#ifndef O_CLOEXEC
int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
(void)r;
assert(r == 0 && "fcntl(F_SETFD, FD_CLOEXEC) failed");
#endif
+ return std::error_code();
+}
+
+std::error_code openFileForRead(const Twine &Name, int &ResultFD,
+ OpenFlags Flags,
+ SmallVectorImpl<char> *RealPath) {
+ std::error_code EC =
+ openFile(Name, ResultFD, CD_OpenExisting, FA_Read, Flags, 0666);
+ if (EC)
+ return EC;
+
// Attempt to get the real name of the file, if the user asked
if(!RealPath)
return std::error_code();
@@ -756,6 +804,9 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD,
if (CharCount > 0)
RealPath->append(Buffer, Buffer + CharCount);
} else {
+ SmallString<128> Storage;
+ StringRef P = Name.toNullTerminatedStringRef(Storage);
+
// Use ::realpath to get the real path name
if (::realpath(P.begin(), Buffer) != nullptr)
RealPath->append(Buffer, Buffer + strlen(Buffer));
@@ -764,56 +815,42 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD,
return std::error_code();
}
-Expected<file_t> openNativeFileForRead(const Twine &Name,
+Expected<file_t> openNativeFileForRead(const Twine &Name, OpenFlags Flags,
SmallVectorImpl<char> *RealPath) {
file_t ResultFD;
- std::error_code EC = openFileForRead(Name, ResultFD, RealPath);
+ std::error_code EC = openFileForRead(Name, ResultFD, Flags, 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".
- assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) &&
- "Cannot specify both 'excl' and 'append' file creation flags!");
-
- int OpenFlags = O_CREAT;
-
-#ifdef O_CLOEXEC
- OpenFlags |= O_CLOEXEC;
-#endif
-
- if (Flags & F_RW)
- OpenFlags |= O_RDWR;
- else
- OpenFlags |= O_WRONLY;
-
- if (Flags & F_Append)
- OpenFlags |= O_APPEND;
- else if (!(Flags & F_NoTrunc))
- OpenFlags |= O_TRUNC;
+ CreationDisposition Disp, OpenFlags Flags,
+ unsigned Mode) {
+ return openFile(Name, ResultFD, Disp, FA_Write, Flags, Mode);
+}
- if (Flags & F_Excl)
- OpenFlags |= O_EXCL;
+Expected<file_t> openNativeFileForWrite(const Twine &Name,
+ CreationDisposition Disp,
+ OpenFlags Flags, unsigned Mode) {
+ file_t ResultFD;
+ std::error_code EC = openFileForWrite(Name, ResultFD, Disp, Flags, Mode);
+ if (EC)
+ return errorCodeToError(EC);
+ return ResultFD;
+}
- SmallString<128> Storage;
- StringRef P = Name.toNullTerminatedStringRef(Storage);
- if ((ResultFD = sys::RetryAfterSignal(-1, open, P.begin(), OpenFlags, Mode)) < 0)
- return std::error_code(errno, std::generic_category());
-#ifndef O_CLOEXEC
- int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
- (void)r;
- assert(r == 0 && "fcntl(F_SETFD, FD_CLOEXEC) failed");
-#endif
- return std::error_code();
+std::error_code openFileForReadWrite(const Twine &Name, int &ResultFD,
+ CreationDisposition Disp, OpenFlags Flags,
+ unsigned Mode) {
+ return openFile(Name, ResultFD, Disp, FA_Read | FA_Write, Flags, Mode);
}
-Expected<file_t> openNativeFileForWrite(const Twine &Name, OpenFlags Flags,
- unsigned Mode) {
+Expected<file_t> openNativeFileForReadWrite(const Twine &Name,
+ CreationDisposition Disp,
+ OpenFlags Flags, unsigned Mode) {
file_t ResultFD;
- std::error_code EC = openFileForWrite(Name, ResultFD, Flags, Mode);
+ std::error_code EC = openFileForReadWrite(Name, ResultFD, Disp, Flags, Mode);
if (EC)
return errorCodeToError(EC);
return ResultFD;
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index 3f6aa114505..a7e2a75dc0c 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -1035,31 +1035,20 @@ ErrorOr<basic_file_status> directory_entry::status() const {
return Status;
}
-static std::error_code directoryRealPath(const Twine &Name,
- SmallVectorImpl<char> &RealPath) {
- SmallVector<wchar_t, 128> PathUTF16;
+static std::error_code nativeFileToFd(Expected<HANDLE> H, int &ResultFD,
+ OpenFlags Flags) {
+ int CrtOpenFlags = 0;
+ if (Flags & OF_Append)
+ CrtOpenFlags |= _O_APPEND;
- if (std::error_code EC = widenPath(Name, PathUTF16))
- return EC;
+ if (Flags & OF_Text)
+ CrtOpenFlags |= _O_TEXT;
- HANDLE H =
- ::CreateFileW(PathUTF16.begin(), GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
- if (H == INVALID_HANDLE_VALUE)
- return mapWindowsError(GetLastError());
- std::error_code EC = realPathFromHandle(H, RealPath);
- ::CloseHandle(H);
- 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);
+ ResultFD = ::_open_osfhandle(intptr_t(*H), CrtOpenFlags);
if (ResultFD == -1) {
::CloseHandle(*H);
return mapWindowsError(ERROR_INVALID_HANDLE);
@@ -1067,23 +1056,62 @@ static std::error_code nativeFileToFd(Expected<HANDLE> H, int &ResultFD,
return std::error_code();
}
-std::error_code openFileForRead(const Twine &Name, int &ResultFD,
- SmallVectorImpl<char> *RealPath) {
- Expected<HANDLE> NativeFile = openNativeFileForRead(Name, RealPath);
- return nativeFileToFd(std::move(NativeFile), ResultFD, 0);
+static DWORD nativeOpenFlags(OpenFlags Flags) {
+ DWORD Result = 0;
+ if (Flags & OF_Delete)
+ Result |= FILE_FLAG_DELETE_ON_CLOSE;
+
+ if (Result == 0)
+ Result = FILE_ATTRIBUTE_NORMAL;
+ return Result;
+}
+
+static DWORD nativeDisposition(CreationDisposition Disp, OpenFlags Flags) {
+ // This is a compatibility hack. Really we should respect the creation
+ // disposition, but a lot of old code relied on the implicit assumption that
+ // OF_Append implied it would open an existing file. Since the disposition is
+ // now explicit and defaults to CD_CreateAlways, this assumption would cause
+ // any usage of OF_Append to append to a new file, even if the file already
+ // existed. A better solution might have two new creation dispositions:
+ // CD_AppendAlways and CD_AppendNew. This would also address the problem of
+ // OF_Append being used on a read-only descriptor, which doesn't make sense.
+ if (Flags & OF_Append)
+ return OPEN_ALWAYS;
+
+ switch (Disp) {
+ case CD_CreateAlways:
+ return CREATE_ALWAYS;
+ case CD_CreateNew:
+ return CREATE_NEW;
+ case CD_OpenAlways:
+ return OPEN_ALWAYS;
+ case CD_OpenExisting:
+ return OPEN_EXISTING;
+ }
+ llvm_unreachable("unreachable!");
}
-Expected<file_t> openNativeFileForRead(const Twine &Name,
- SmallVectorImpl<char> *RealPath) {
- SmallVector<wchar_t, 128> PathUTF16;
+static DWORD nativeAccess(FileAccess Access, OpenFlags Flags) {
+ DWORD Result = 0;
+ if (Access & FA_Read)
+ Result |= GENERIC_READ;
+ if (Access & FA_Write)
+ Result |= GENERIC_WRITE;
+ if (Flags & OF_Delete)
+ Result |= DELETE;
+ return Result;
+}
+static Expected<file_t> nativeOpenFile(const Twine &Name, DWORD Disp,
+ DWORD Access, DWORD Flags) {
+ SmallVector<wchar_t, 128> PathUTF16;
if (std::error_code EC = widenPath(Name, PathUTF16))
return errorCodeToError(EC);
HANDLE H =
- ::CreateFileW(PathUTF16.begin(), GENERIC_READ,
+ ::CreateFileW(PathUTF16.begin(), Access,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ NULL, Disp, Flags, NULL);
if (H == INVALID_HANDLE_VALUE) {
DWORD LastError = ::GetLastError();
std::error_code EC = mapWindowsError(LastError);
@@ -1096,74 +1124,84 @@ Expected<file_t> openNativeFileForRead(const Twine &Name,
return errorCodeToError(make_error_code(errc::is_a_directory));
return errorCodeToError(EC);
}
+ return H;
+}
- // Fetch the real name of the file, if the user asked
- if (RealPath)
- realPathFromHandle(H, *RealPath);
+static Expected<file_t> openFile(const Twine &Name, CreationDisposition Disp,
+ FileAccess Access, OpenFlags Flags) {
+ // Verify that we don't have both "append" and "excl".
+ assert((!(Disp == CD_CreateNew) || !(Flags & OF_Append)) &&
+ "Cannot specify both 'CreateNew' and 'Append' file creation flags!");
- return H;
+ DWORD NativeFlags = nativeOpenFlags(Flags);
+ DWORD NativeDisp = nativeDisposition(Disp, Flags);
+ DWORD NativeAccess = nativeAccess(Access, Flags);
+
+ return nativeOpenFile(Name, NativeDisp, NativeAccess, NativeFlags);
}
-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;
+static std::error_code directoryRealPath(const Twine &Name,
+ SmallVectorImpl<char> &RealPath) {
+ Expected<file_t> EF = nativeOpenFile(Name, OPEN_EXISTING, GENERIC_READ,
+ FILE_FLAG_BACKUP_SEMANTICS);
+ if (!EF)
+ return errorToErrorCode(EF.takeError());
- if (Flags & F_Text)
- OpenFlags |= _O_TEXT;
+ std::error_code EC = realPathFromHandle(*EF, RealPath);
+ ::CloseHandle(*EF);
+ return EC;
+}
- Expected<HANDLE> NativeFile = openNativeFileForWrite(Name, Flags, Mode);
- return nativeFileToFd(std::move(NativeFile), ResultFD, OpenFlags);
+std::error_code openFileForRead(const Twine &Name, int &ResultFD,
+ OpenFlags Flags,
+ SmallVectorImpl<char> *RealPath) {
+ Expected<HANDLE> NativeFile = openNativeFileForRead(Name, Flags, RealPath);
+ return nativeFileToFd(std::move(NativeFile), ResultFD, OF_None);
}
-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!");
+Expected<file_t> openNativeFileForRead(const Twine &Name, OpenFlags Flags,
+ SmallVectorImpl<char> *RealPath) {
- SmallVector<wchar_t, 128> PathUTF16;
+ Expected<file_t> Result = openFile(Name, CD_OpenExisting, FA_Read, Flags);
- if (std::error_code EC = widenPath(Name, PathUTF16))
- return errorCodeToError(EC);
+ // Fetch the real name of the file, if the user asked
+ if (Result && RealPath)
+ realPathFromHandle(*Result, *RealPath);
- DWORD CreationDisposition;
- if (Flags & F_Excl)
- CreationDisposition = CREATE_NEW;
- else if ((Flags & F_Append) || (Flags & F_NoTrunc))
- CreationDisposition = OPEN_ALWAYS;
- else
- CreationDisposition = CREATE_ALWAYS;
-
- DWORD Access = GENERIC_WRITE;
- DWORD Attributes = FILE_ATTRIBUTE_NORMAL;
- if (Flags & F_RW)
- Access |= GENERIC_READ;
- if (Flags & F_Delete) {
- Access |= DELETE;
- Attributes |= FILE_FLAG_DELETE_ON_CLOSE;
- }
+ return std::move(Result);
+}
- HANDLE H =
- ::CreateFileW(PathUTF16.data(), Access,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL, CreationDisposition, Attributes, NULL);
+std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
+ CreationDisposition Disp, OpenFlags Flags,
+ unsigned Mode) {
+ Expected<HANDLE> NativeFile = openNativeFileForWrite(Name, Disp, Flags, Mode);
+ if (!NativeFile)
+ return errorToErrorCode(NativeFile.takeError());
- if (H == INVALID_HANDLE_VALUE) {
- DWORD LastError = ::GetLastError();
- std::error_code EC = mapWindowsError(LastError);
- // Provide a better error message when trying to open directories.
- // This only runs if we failed to open the file, so there is probably
- // no performances issues.
- if (LastError != ERROR_ACCESS_DENIED)
- return errorCodeToError(EC);
- if (is_directory(Name))
- return errorCodeToError(make_error_code(errc::is_a_directory));
- return errorCodeToError(EC);
- }
+ return nativeFileToFd(std::move(NativeFile), ResultFD, Flags);
+}
- return H;
+Expected<file_t> openNativeFileForWrite(const Twine &Name,
+ CreationDisposition Disp,
+ OpenFlags Flags, unsigned Mode) {
+ return openFile(Name, Disp, FA_Write, Flags);
+}
+
+std::error_code openFileForReadWrite(const Twine &Name, int &ResultFD,
+ CreationDisposition Disp, OpenFlags Flags,
+ unsigned Mode) {
+ Expected<HANDLE> NativeFile =
+ openNativeFileForReadWrite(Name, Disp, Flags, Mode);
+ if (!NativeFile)
+ return errorToErrorCode(NativeFile.takeError());
+
+ return nativeFileToFd(std::move(NativeFile), ResultFD, Flags);
+}
+
+Expected<file_t> openNativeFileForReadWrite(const Twine &Name,
+ CreationDisposition Disp,
+ OpenFlags Flags, unsigned Mode) {
+ return openFile(Name, Disp, FA_Write | FA_Read, Flags);
}
void closeFile(file_t &F) {
@@ -1239,7 +1277,8 @@ std::error_code real_path(const Twine &path, SmallVectorImpl<char> &dest,
return directoryRealPath(path, dest);
int fd;
- if (std::error_code EC = llvm::sys::fs::openFileForRead(path, fd, &dest))
+ if (std::error_code EC =
+ llvm::sys::fs::openFileForRead(path, fd, OF_None, &dest))
return EC;
::close(fd);
return std::error_code();
diff --git a/llvm/lib/Support/Windows/Program.inc b/llvm/lib/Support/Windows/Program.inc
index 73542c19dc3..0dcd305d1eb 100644
--- a/llvm/lib/Support/Windows/Program.inc
+++ b/llvm/lib/Support/Windows/Program.inc
@@ -496,7 +496,7 @@ std::error_code
llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
WindowsEncodingMethod Encoding) {
std::error_code EC;
- llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::F_Text);
+ llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::F_Text);
if (EC)
return EC;
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 3de063449f7..e1e5fe718b8 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -498,29 +498,56 @@ void format_object_base::home() {
//===----------------------------------------------------------------------===//
static int getFD(StringRef Filename, std::error_code &EC,
+ sys::fs::CreationDisposition Disp, sys::fs::FileAccess Access,
sys::fs::OpenFlags Flags) {
+ assert((Access & sys::fs::FA_Write) &&
+ "Cannot make a raw_ostream from a read-only descriptor!");
+
// Handle "-" as stdout. Note that when we do this, we consider ourself
// the owner of stdout and may set the "binary" flag globally based on Flags.
if (Filename == "-") {
EC = std::error_code();
// If user requested binary then put stdout into binary mode if
// possible.
- if (!(Flags & sys::fs::F_Text))
+ if (!(Flags & sys::fs::OF_Text))
sys::ChangeStdoutToBinary();
return STDOUT_FILENO;
}
int FD;
- EC = sys::fs::openFileForWrite(Filename, FD, Flags);
+ if (Access & sys::fs::FA_Read)
+ EC = sys::fs::openFileForReadWrite(Filename, FD, Disp, Flags);
+ else
+ EC = sys::fs::openFileForWrite(Filename, FD, Disp, Flags);
if (EC)
return -1;
return FD;
}
+raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC)
+ : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
+ sys::fs::OF_None) {}
+
+raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
+ sys::fs::CreationDisposition Disp)
+ : raw_fd_ostream(Filename, EC, Disp, sys::fs::FA_Write, sys::fs::OF_None) {}
+
+raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
+ sys::fs::FileAccess Access)
+ : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, Access,
+ sys::fs::OF_None) {}
+
+raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
+ sys::fs::OpenFlags Flags)
+ : raw_fd_ostream(Filename, EC, sys::fs::CD_CreateAlways, sys::fs::FA_Write,
+ Flags) {}
+
raw_fd_ostream::raw_fd_ostream(StringRef Filename, std::error_code &EC,
+ sys::fs::CreationDisposition Disp,
+ sys::fs::FileAccess Access,
sys::fs::OpenFlags Flags)
- : raw_fd_ostream(getFD(Filename, EC, Flags), true) {}
+ : raw_fd_ostream(getFD(Filename, EC, Disp, Access, Flags), true) {}
/// FD is the file descriptor that this writes to. If ShouldClose is true, this
/// closes the file when the stream is destroyed.
OpenPOWER on IntegriCloud