1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

Expose a single global file open function.

This one allows much more flexibility than the standard
openFileForRead / openFileForWrite functions.  Since there is now
just one "real" function that does the work, all other implementations
simply delegate to this one.

llvm-svn: 334246
This commit is contained in:
Zachary Turner 2018-06-07 23:25:13 +00:00
parent ea67986297
commit 27a9be49ad
3 changed files with 126 additions and 111 deletions

View File

@ -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<file_t> 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<file_t> 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<file_t> 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<file_t> openNativeFileForReadWrite(const Twine &Name,
inline Expected<file_t> 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<file_t> 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.

View File

@ -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<int> 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<char> *RealPath) {
@ -824,38 +835,6 @@ Expected<file_t> 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<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;
}
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> 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;

View File

@ -1102,11 +1102,12 @@ static DWORD nativeAccess(FileAccess Access, OpenFlags Flags) {
return Result;
}
static Expected<file_t> 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<wchar_t, 128> 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<file_t> 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<file_t> openFile(const Twine &Name, CreationDisposition Disp,
FileAccess Access, OpenFlags Flags) {
Expected<file_t> 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<file_t> 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<file_t> 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<char> &RealPath) {
Expected<file_t> 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<file_t> openNativeFileForRead(const Twine &Name, OpenFlags Flags,
SmallVectorImpl<char> *RealPath) {
Expected<file_t> Result = openFile(Name, CD_OpenExisting, FA_Read, Flags);
Expected<file_t> 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<file_t> 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<HANDLE> NativeFile = openNativeFileForWrite(Name, Disp, Flags, Mode);
if (!NativeFile)
return errorToErrorCode(NativeFile.takeError());
return nativeFileToFd(std::move(NativeFile), ResultFD, Flags);
}
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) {
::CloseHandle(F);
F = kInvalidFile;