mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
[Support] Add the option to not follow symlinks on stat.
llvm-svn: 297154
This commit is contained in:
parent
940b1e3dcf
commit
da5b1975f1
@ -481,9 +481,9 @@ inline bool is_local(int FD) {
|
|||||||
|
|
||||||
/// @brief Does status represent a directory?
|
/// @brief Does status represent a directory?
|
||||||
///
|
///
|
||||||
/// @param status A file_status previously returned from status.
|
/// @param Path The path to get the type of.
|
||||||
/// @returns status.type() == file_type::directory_file.
|
/// @returns A value from the file_type enumeration indicating the type of file.
|
||||||
file_type get_file_type(const Twine &Path);
|
file_type get_file_type(const Twine &Path, bool follow = true);
|
||||||
|
|
||||||
/// @brief Does status represent a directory?
|
/// @brief Does status represent a directory?
|
||||||
///
|
///
|
||||||
@ -552,9 +552,12 @@ std::error_code is_other(const Twine &path, bool &result);
|
|||||||
///
|
///
|
||||||
/// @param path Input path.
|
/// @param path Input path.
|
||||||
/// @param result Set to the file status.
|
/// @param result Set to the file status.
|
||||||
|
/// @param follow When true, follows symlinks. Otherwise, the symlink itself is
|
||||||
|
/// statted.
|
||||||
/// @returns errc::success if result has been successfully set, otherwise a
|
/// @returns errc::success if result has been successfully set, otherwise a
|
||||||
/// platform-specific error_code.
|
/// platform-specific error_code.
|
||||||
std::error_code status(const Twine &path, file_status &result);
|
std::error_code status(const Twine &path, file_status &result,
|
||||||
|
bool follow = true);
|
||||||
|
|
||||||
/// @brief A version for when a file descriptor is already available.
|
/// @brief A version for when a file descriptor is already available.
|
||||||
std::error_code status(int FD, file_status &Result);
|
std::error_code status(int FD, file_status &Result);
|
||||||
|
@ -953,9 +953,9 @@ bool status_known(file_status s) {
|
|||||||
return s.type() != file_type::status_error;
|
return s.type() != file_type::status_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_type get_file_type(const Twine &Path) {
|
file_type get_file_type(const Twine &Path, bool Follow) {
|
||||||
file_status st;
|
file_status st;
|
||||||
if (status(Path, st))
|
if (status(Path, st, Follow))
|
||||||
return file_type::status_error;
|
return file_type::status_error;
|
||||||
return st.type();
|
return st.type();
|
||||||
}
|
}
|
||||||
|
@ -510,12 +510,12 @@ static std::error_code fillStatus(int StatRet, const struct stat &Status,
|
|||||||
return std::error_code();
|
return std::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::error_code status(const Twine &Path, file_status &Result) {
|
std::error_code status(const Twine &Path, file_status &Result, bool Follow) {
|
||||||
SmallString<128> PathStorage;
|
SmallString<128> PathStorage;
|
||||||
StringRef P = Path.toNullTerminatedStringRef(PathStorage);
|
StringRef P = Path.toNullTerminatedStringRef(PathStorage);
|
||||||
|
|
||||||
struct stat Status;
|
struct stat Status;
|
||||||
int StatRet = ::stat(P.begin(), &Status);
|
int StatRet = (Follow ? ::stat : ::lstat)(P.begin(), &Status);
|
||||||
return fillStatus(StatRet, Status, Result);
|
return fillStatus(StatRet, Status, Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,7 +551,7 @@ handle_status_error:
|
|||||||
return mapWindowsError(LastError);
|
return mapWindowsError(LastError);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::error_code status(const Twine &path, file_status &result) {
|
std::error_code status(const Twine &path, file_status &result, bool Follow) {
|
||||||
SmallString<128> path_storage;
|
SmallString<128> path_storage;
|
||||||
SmallVector<wchar_t, 128> path_utf16;
|
SmallVector<wchar_t, 128> path_utf16;
|
||||||
|
|
||||||
@ -568,28 +568,19 @@ std::error_code status(const Twine &path, file_status &result) {
|
|||||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||||
return getStatus(INVALID_HANDLE_VALUE, result);
|
return getStatus(INVALID_HANDLE_VALUE, result);
|
||||||
|
|
||||||
|
DWORD Flags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||||
// Handle reparse points.
|
// Handle reparse points.
|
||||||
if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
|
if (!Follow && (attr & FILE_ATTRIBUTE_REPARSE_POINT))
|
||||||
ScopedFileHandle h(
|
Flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||||
::CreateFileW(path_utf16.begin(),
|
|
||||||
0, // Attributes only.
|
|
||||||
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
||||||
NULL,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_FLAG_BACKUP_SEMANTICS,
|
|
||||||
0));
|
|
||||||
if (!h)
|
|
||||||
return getStatus(INVALID_HANDLE_VALUE, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedFileHandle h(
|
ScopedFileHandle h(
|
||||||
::CreateFileW(path_utf16.begin(), 0, // Attributes only.
|
::CreateFileW(path_utf16.begin(), 0, // Attributes only.
|
||||||
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
|
NULL, OPEN_EXISTING, Flags, 0));
|
||||||
if (!h)
|
if (!h)
|
||||||
return getStatus(INVALID_HANDLE_VALUE, result);
|
return getStatus(INVALID_HANDLE_VALUE, result);
|
||||||
|
|
||||||
return getStatus(h, result);
|
return getStatus(h, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::error_code status(int FD, file_status &Result) {
|
std::error_code status(int FD, file_status &Result) {
|
||||||
|
Loading…
Reference in New Issue
Block a user