diff options
Diffstat (limited to 'llvm/lib/Support')
-rw-r--r-- | llvm/lib/Support/FileOutputBuffer.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Support/MemoryBuffer.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Support/Path.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/Support/TarWriter.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Support/Unix/Path.inc | 125 | ||||
-rw-r--r-- | llvm/lib/Support/Windows/Path.inc | 205 | ||||
-rw-r--r-- | llvm/lib/Support/Windows/Program.inc | 2 | ||||
-rw-r--r-- | llvm/lib/Support/raw_ostream.cpp | 33 |
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. |