diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index baec6139d35..a17a9f51036 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -849,9 +849,8 @@ inline FileAccess &operator|=(FileAccess &A, FileAccess B) { return A; } -/// @brief Opens the file with the given name in a write-only or read-write -/// mode, returning its open file descriptor. If the file does not exist, it -/// is created. +/// @brief Opens a file with the specified creation disposition, access mode, +/// and flags and returns a file descriptor. /// /// The caller is responsible for closing the file descriptor once they are /// finished with it. @@ -859,32 +858,36 @@ inline FileAccess &operator|=(FileAccess &A, FileAccess B) { /// @param Name The path of the file to open, relative or absolute. /// @param ResultFD If the file could be opened successfully, its descriptor /// is stored in this location. Otherwise, this is set to -1. -/// @param Flags Additional flags used to determine whether the file should be -/// opened in, for example, read-write or in write-only mode. +/// @param Disp Value specifying the existing-file behavior. +/// @param Access Value specifying whether to open the file in read, write, or +/// read-write mode. +/// @param Flags Additional flags. /// @param Mode The access permissions of the file, represented in octal. /// @returns errc::success if \a Name has been opened, otherwise a /// platform-specific error_code. -std::error_code openFileForWrite(const Twine &Name, int &ResultFD, - CreationDisposition Disp = CD_CreateAlways, - OpenFlags Flags = OF_None, - unsigned Mode = 0666); +std::error_code openFile(const Twine &Name, int &ResultFD, + CreationDisposition Disp, FileAccess Access, + OpenFlags Flags, unsigned Mode = 0666); -/// @brief Opens the file with the given name in a write-only or read-write -/// mode, returning its open file descriptor. If the file does not exist, it -/// is created. +/// @brief Opens a file with the specified creation disposition, access mode, +/// and flags and returns a platform-specific file object. /// -/// The caller is responsible for closing the freeing the file once they are +/// The caller is responsible for closing the file object once they are /// finished with it. /// /// @param Name The path of the file to open, relative or absolute. -/// @param Flags Additional flags used to determine whether the file should be -/// opened in, for example, read-write or in write-only mode. +/// @param ResultFD If the file could be opened successfully, its descriptor +/// is stored in this location. Otherwise, this is set to -1. +/// @param Disp Value specifying the existing-file behavior. +/// @param Access Value specifying whether to open the file in read, write, or +/// read-write mode. +/// @param Flags Additional flags. /// @param Mode The access permissions of the file, represented in octal. -/// @returns a platform-specific file descriptor if \a Name has been opened, -/// otherwise an error object. -Expected openNativeFileForWrite(const Twine &Name, - CreationDisposition Disp, - OpenFlags Flags, unsigned Mode = 0666); +/// @returns errc::success if \a Name has been opened, otherwise a +/// platform-specific error_code. +Expected openNativeFile(const Twine &Name, CreationDisposition Disp, + FileAccess Access, OpenFlags Flags, + unsigned Mode = 0666); /// @brief Opens the file with the given name in a write-only or read-write /// mode, returning its open file descriptor. If the file does not exist, it @@ -901,9 +904,12 @@ Expected openNativeFileForWrite(const Twine &Name, /// @param Mode The access permissions of the file, represented in octal. /// @returns errc::success if \a Name has been opened, otherwise a /// platform-specific error_code. -std::error_code openFileForReadWrite(const Twine &Name, int &ResultFD, - CreationDisposition Disp, OpenFlags Flags, - unsigned Mode = 0666); +inline std::error_code +openFileForWrite(const Twine &Name, int &ResultFD, + CreationDisposition Disp = CD_CreateAlways, + OpenFlags Flags = OF_None, unsigned Mode = 0666) { + return openFile(Name, ResultFD, Disp, FA_Write, Flags, Mode); +} /// @brief Opens the file with the given name in a write-only or read-write /// mode, returning its open file descriptor. If the file does not exist, it @@ -918,10 +924,54 @@ std::error_code openFileForReadWrite(const Twine &Name, int &ResultFD, /// @param Mode The access permissions of the file, represented in octal. /// @returns a platform-specific file descriptor if \a Name has been opened, /// otherwise an error object. -Expected openNativeFileForReadWrite(const Twine &Name, +inline Expected openNativeFileForWrite(const Twine &Name, + CreationDisposition Disp, + OpenFlags Flags, + unsigned Mode = 0666) { + return openNativeFile(Name, Disp, FA_Write, Flags, Mode); +} + +/// @brief Opens the file with the given name in a write-only or read-write +/// mode, returning its open file descriptor. If the file does not exist, it +/// is created. +/// +/// The caller is responsible for closing the file descriptor once they are +/// finished with it. +/// +/// @param Name The path of the file to open, relative or absolute. +/// @param ResultFD If the file could be opened successfully, its descriptor +/// is stored in this location. Otherwise, this is set to -1. +/// @param Flags Additional flags used to determine whether the file should be +/// opened in, for example, read-write or in write-only mode. +/// @param Mode The access permissions of the file, represented in octal. +/// @returns errc::success if \a Name has been opened, otherwise a +/// platform-specific error_code. +inline std::error_code openFileForReadWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp, OpenFlags Flags, - unsigned Mode = 0666); + unsigned Mode = 0666) { + return openFile(Name, ResultFD, Disp, FA_Write | FA_Read, Flags, Mode); +} + +/// @brief Opens the file with the given name in a write-only or read-write +/// mode, returning its open file descriptor. If the file does not exist, it +/// is created. +/// +/// The caller is responsible for closing the freeing the file once they are +/// finished with it. +/// +/// @param Name The path of the file to open, relative or absolute. +/// @param Flags Additional flags used to determine whether the file should be +/// opened in, for example, read-write or in write-only mode. +/// @param Mode The access permissions of the file, represented in octal. +/// @returns a platform-specific file descriptor if \a Name has been opened, +/// otherwise an error object. +inline Expected openNativeFileForReadWrite(const Twine &Name, + CreationDisposition Disp, + OpenFlags Flags, + unsigned Mode = 0666) { + return openNativeFile(Name, Disp, FA_Write | FA_Read, Flags, Mode); +} /// @brief Opens the file with the given name in a read-only mode, returning /// its open file descriptor. diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc index 59d2cb58cf0..c4c4cfc3afe 100644 --- a/lib/Support/Unix/Path.inc +++ b/lib/Support/Unix/Path.inc @@ -759,9 +759,9 @@ static int nativeOpenFlags(CreationDisposition Disp, OpenFlags Flags, return Result; } -static std::error_code openFile(const Twine &Name, int &ResultFD, - CreationDisposition Disp, FileAccess Access, - OpenFlags Flags, unsigned Mode) { +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; @@ -777,6 +777,17 @@ static std::error_code openFile(const Twine &Name, int &ResultFD, return std::error_code(); } +Expected openNativeFile(const Twine &Name, CreationDisposition Disp, + FileAccess Access, OpenFlags Flags, + unsigned Mode) { + + int FD; + std::error_code EC = openFile(Name, FD, Disp, Access, Flags, Mode); + if (EC) + return errorCodeToError(EC); + return FD; +} + std::error_code openFileForRead(const Twine &Name, int &ResultFD, OpenFlags Flags, SmallVectorImpl *RealPath) { @@ -824,38 +835,6 @@ Expected openNativeFileForRead(const Twine &Name, OpenFlags Flags, return ResultFD; } -std::error_code openFileForWrite(const Twine &Name, int &ResultFD, - CreationDisposition Disp, OpenFlags Flags, - unsigned Mode) { - return openFile(Name, ResultFD, Disp, FA_Write, Flags, Mode); -} - -Expected 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; -} - -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 openNativeFileForReadWrite(const Twine &Name, - CreationDisposition Disp, - OpenFlags Flags, unsigned Mode) { - file_t ResultFD; - std::error_code EC = openFileForReadWrite(Name, ResultFD, Disp, Flags, Mode); - if (EC) - return errorCodeToError(EC); - return ResultFD; -} - void closeFile(file_t &F) { ::close(F); F = kInvalidFile; diff --git a/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc index a7e2a75dc0c..6017fcedc33 100644 --- a/lib/Support/Windows/Path.inc +++ b/lib/Support/Windows/Path.inc @@ -1102,11 +1102,12 @@ static DWORD nativeAccess(FileAccess Access, OpenFlags Flags) { return Result; } -static Expected nativeOpenFile(const Twine &Name, DWORD Disp, - DWORD Access, DWORD Flags) { +static std::error_code openNativeFileInternal(const Twine &Name, + file_t &ResultFile, DWORD Disp, + DWORD Access, DWORD Flags) { SmallVector PathUTF16; if (std::error_code EC = widenPath(Name, PathUTF16)) - return errorCodeToError(EC); + return EC; HANDLE H = ::CreateFileW(PathUTF16.begin(), Access, @@ -1119,16 +1120,18 @@ static Expected nativeOpenFile(const Twine &Name, DWORD Disp, // 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); + return EC; if (is_directory(Name)) - return errorCodeToError(make_error_code(errc::is_a_directory)); - return errorCodeToError(EC); + return make_error_code(errc::is_a_directory); + return EC; } - return H; + ResultFile = H; + return std::error_code(); } -static Expected openFile(const Twine &Name, CreationDisposition Disp, - FileAccess Access, OpenFlags Flags) { +Expected openNativeFile(const Twine &Name, CreationDisposition Disp, + FileAccess Access, OpenFlags Flags, + unsigned Mode) { // 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!"); @@ -1137,18 +1140,34 @@ static Expected openFile(const Twine &Name, CreationDisposition Disp, DWORD NativeDisp = nativeDisposition(Disp, Flags); DWORD NativeAccess = nativeAccess(Access, Flags); - return nativeOpenFile(Name, NativeDisp, NativeAccess, NativeFlags); + file_t Result; + std::error_code EC = openNativeFileInternal(Name, Result, NativeDisp, + NativeAccess, NativeFlags); + if (EC) + return errorCodeToError(EC); + return Result; +} + +std::error_code openFile(const Twine &Name, int &ResultFD, + CreationDisposition Disp, FileAccess Access, + OpenFlags Flags, unsigned int Mode) { + Expected Result = openNativeFile(Name, Disp, Access, Flags); + if (!Result) + return errorToErrorCode(Result.takeError()); + + return nativeFileToFd(*Result, ResultFD, Flags); } static std::error_code directoryRealPath(const Twine &Name, SmallVectorImpl &RealPath) { - Expected EF = nativeOpenFile(Name, OPEN_EXISTING, GENERIC_READ, - FILE_FLAG_BACKUP_SEMANTICS); - if (!EF) - return errorToErrorCode(EF.takeError()); + file_t File; + std::error_code EC = openNativeFileInternal( + Name, File, OPEN_EXISTING, GENERIC_READ, FILE_FLAG_BACKUP_SEMANTICS); + if (EC) + return EC; - std::error_code EC = realPathFromHandle(*EF, RealPath); - ::CloseHandle(*EF); + EC = realPathFromHandle(File, RealPath); + ::CloseHandle(File); return EC; } @@ -1161,8 +1180,8 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD, Expected openNativeFileForRead(const Twine &Name, OpenFlags Flags, SmallVectorImpl *RealPath) { - - Expected Result = openFile(Name, CD_OpenExisting, FA_Read, Flags); + Expected Result = + openNativeFile(Name, CD_OpenExisting, FA_Read, Flags); // Fetch the real name of the file, if the user asked if (Result && RealPath) @@ -1171,39 +1190,6 @@ Expected openNativeFileForRead(const Twine &Name, OpenFlags Flags, return std::move(Result); } -std::error_code openFileForWrite(const Twine &Name, int &ResultFD, - CreationDisposition Disp, OpenFlags Flags, - unsigned Mode) { - Expected NativeFile = openNativeFileForWrite(Name, Disp, Flags, Mode); - if (!NativeFile) - return errorToErrorCode(NativeFile.takeError()); - - return nativeFileToFd(std::move(NativeFile), ResultFD, Flags); -} - -Expected 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 NativeFile = - openNativeFileForReadWrite(Name, Disp, Flags, Mode); - if (!NativeFile) - return errorToErrorCode(NativeFile.takeError()); - - return nativeFileToFd(std::move(NativeFile), ResultFD, Flags); -} - -Expected openNativeFileForReadWrite(const Twine &Name, - CreationDisposition Disp, - OpenFlags Flags, unsigned Mode) { - return openFile(Name, Disp, FA_Write | FA_Read, Flags); -} - void closeFile(file_t &F) { ::CloseHandle(F); F = kInvalidFile;