Skip to content

Commit

Permalink
[Support] Add the option to not follow symlinks on stat.
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297154 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Zachary Turner committed Mar 7, 2017
1 parent 2a998c0 commit 6a2cb81
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 25 deletions.
11 changes: 7 additions & 4 deletions include/llvm/Support/FileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,9 +481,9 @@ inline bool is_local(int FD) {

/// @brief Does status represent a directory?
///
/// @param status A file_status previously returned from status.
/// @returns status.type() == file_type::directory_file.
file_type get_file_type(const Twine &Path);
/// @param Path The path to get the type of.
/// @returns A value from the file_type enumeration indicating the type of file.
file_type get_file_type(const Twine &Path, bool follow = true);

/// @brief Does status represent a directory?
///
Expand Down Expand Up @@ -552,9 +552,12 @@ std::error_code is_other(const Twine &path, bool &result);
///
/// @param path Input path.
/// @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
/// 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.
std::error_code status(int FD, file_status &Result);
Expand Down
4 changes: 2 additions & 2 deletions lib/Support/Path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -953,9 +953,9 @@ bool status_known(file_status s) {
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;
if (status(Path, st))
if (status(Path, st, Follow))
return file_type::status_error;
return st.type();
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Support/Unix/Path.inc
Original file line number Diff line number Diff line change
Expand Up @@ -510,12 +510,12 @@ static std::error_code fillStatus(int StatRet, const struct stat &Status,
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;
StringRef P = Path.toNullTerminatedStringRef(PathStorage);

struct stat Status;
int StatRet = ::stat(P.begin(), &Status);
int StatRet = (Follow ? ::stat : ::lstat)(P.begin(), &Status);
return fillStatus(StatRet, Status, Result);
}

Expand Down
25 changes: 8 additions & 17 deletions lib/Support/Windows/Path.inc
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ handle_status_error:
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;
SmallVector<wchar_t, 128> path_utf16;

Expand All @@ -568,28 +568,19 @@ std::error_code status(const Twine &path, file_status &result) {
if (attr == INVALID_FILE_ATTRIBUTES)
return getStatus(INVALID_HANDLE_VALUE, result);

DWORD Flags = FILE_FLAG_BACKUP_SEMANTICS;
// Handle reparse points.
if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
ScopedFileHandle h(
::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);
}
if (!Follow && (attr & FILE_ATTRIBUTE_REPARSE_POINT))
Flags |= FILE_FLAG_OPEN_REPARSE_POINT;

ScopedFileHandle h(
::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);
NULL, OPEN_EXISTING, Flags, 0));
if (!h)
return getStatus(INVALID_HANDLE_VALUE, result);

return getStatus(h, result);
return getStatus(h, result);
}

std::error_code status(int FD, file_status &Result) {
Expand Down

0 comments on commit 6a2cb81

Please sign in to comment.