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:
parent
ea67986297
commit
27a9be49ad
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user