mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-26 05:25:47 +00:00
Misc cleanups to the FileSytem api.
The main difference is the removal of std::error_code exists(const Twine &path, bool &result); It was an horribly redundant interface since a file not existing is also a valid error_code. Now we have an access function that returns just an error_code. This is the only function that has to be implemented for Unix and Windows. The functions can_write, exists and can_execute an now just wrappers. One still has to be very careful using these function to avoid introducing race conditions (Time of check to time of use). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217625 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -352,33 +352,37 @@ std::error_code resize_file(const Twine &path, uint64_t size);
|
|||||||
/// not.
|
/// not.
|
||||||
bool exists(file_status status);
|
bool exists(file_status status);
|
||||||
|
|
||||||
/// @brief Does file exist?
|
/// @brief Can the file be accessed?
|
||||||
///
|
///
|
||||||
/// @param path Input path.
|
/// @param path Input path.
|
||||||
/// @param result Set to true if the file represented by status exists, false if
|
/// @returns errc::success if the path can be accessed, otherwise a
|
||||||
/// it does not. Undefined otherwise.
|
|
||||||
/// @returns errc::success if result has been successfully set, otherwise a
|
|
||||||
/// platform-specific error_code.
|
/// platform-specific error_code.
|
||||||
std::error_code exists(const Twine &path, bool &result);
|
enum class AccessMode { Exist, Write, Execute };
|
||||||
|
std::error_code access(const Twine &Path, AccessMode Mode);
|
||||||
|
|
||||||
/// @brief Simpler version of exists for clients that don't need to
|
/// @brief Does file exist?
|
||||||
/// differentiate between an error and false.
|
///
|
||||||
inline bool exists(const Twine &path) {
|
/// @param Path Input path.
|
||||||
bool result;
|
/// @returns True if it exists, false otherwise.
|
||||||
return !exists(path, result) && result;
|
inline bool exists(const Twine &Path) {
|
||||||
|
return !access(Path, AccessMode::Exist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Can we execute this file?
|
/// @brief Can we execute this file?
|
||||||
///
|
///
|
||||||
/// @param Path Input path.
|
/// @param Path Input path.
|
||||||
/// @returns True if we can execute it, false otherwise.
|
/// @returns True if we can execute it, false otherwise.
|
||||||
bool can_execute(const Twine &Path);
|
inline bool can_execute(const Twine &Path) {
|
||||||
|
return !access(Path, AccessMode::Execute);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Can we write this file?
|
/// @brief Can we write this file?
|
||||||
///
|
///
|
||||||
/// @param Path Input path.
|
/// @param Path Input path.
|
||||||
/// @returns True if we can write to it, false otherwise.
|
/// @returns True if we can write to it, false otherwise.
|
||||||
bool can_write(const Twine &Path);
|
inline bool can_write(const Twine &Path) {
|
||||||
|
return !access(Path, AccessMode::Write);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Do file_status's represent the same thing?
|
/// @brief Do file_status's represent the same thing?
|
||||||
///
|
///
|
||||||
|
@@ -204,8 +204,8 @@ LockFileManager::WaitForUnlockResult LockFileManager::waitForUnlock() {
|
|||||||
// If the lock file is still expected to be there, check whether it still
|
// If the lock file is still expected to be there, check whether it still
|
||||||
// is.
|
// is.
|
||||||
if (!LockFileGone) {
|
if (!LockFileGone) {
|
||||||
bool Exists;
|
if (sys::fs::access(LockFileName.c_str(), sys::fs::AccessMode::Exist) ==
|
||||||
if (!sys::fs::exists(LockFileName.str(), Exists) && !Exists) {
|
errc::no_such_file_or_directory) {
|
||||||
LockFileGone = true;
|
LockFileGone = true;
|
||||||
LockFileJustDisappeared = true;
|
LockFileJustDisappeared = true;
|
||||||
}
|
}
|
||||||
|
@@ -210,13 +210,13 @@ retry_random_path:
|
|||||||
}
|
}
|
||||||
|
|
||||||
case FS_Name: {
|
case FS_Name: {
|
||||||
bool Exists;
|
std::error_code EC =
|
||||||
std::error_code EC = sys::fs::exists(ResultPath.begin(), Exists);
|
sys::fs::access(ResultPath.begin(), sys::fs::AccessMode::Exist);
|
||||||
|
if (EC == errc::no_such_file_or_directory)
|
||||||
|
return std::error_code();
|
||||||
if (EC)
|
if (EC)
|
||||||
return EC;
|
return EC;
|
||||||
if (Exists)
|
goto retry_random_path;
|
||||||
goto retry_random_path;
|
|
||||||
return std::error_code();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case FS_Dir: {
|
case FS_Dir: {
|
||||||
|
@@ -321,40 +321,37 @@ std::error_code resize_file(const Twine &path, uint64_t size) {
|
|||||||
return std::error_code();
|
return std::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::error_code exists(const Twine &path, bool &result) {
|
static int convertAccessMode(AccessMode Mode) {
|
||||||
SmallString<128> path_storage;
|
switch (Mode) {
|
||||||
StringRef p = path.toNullTerminatedStringRef(path_storage);
|
case AccessMode::Exist:
|
||||||
|
return F_OK;
|
||||||
|
case AccessMode::Write:
|
||||||
|
return W_OK;
|
||||||
|
case AccessMode::Execute:
|
||||||
|
return R_OK | X_OK; // scripts also need R_OK.
|
||||||
|
}
|
||||||
|
llvm_unreachable("invalid enum");
|
||||||
|
}
|
||||||
|
|
||||||
if (::access(p.begin(), F_OK) == -1) {
|
std::error_code access(const Twine &Path, AccessMode Mode) {
|
||||||
if (errno != ENOENT)
|
SmallString<128> PathStorage;
|
||||||
return std::error_code(errno, std::generic_category());
|
StringRef P = Path.toNullTerminatedStringRef(PathStorage);
|
||||||
result = false;
|
|
||||||
} else
|
if (::access(P.begin(), convertAccessMode(Mode)) == -1)
|
||||||
result = true;
|
return std::error_code(errno, std::generic_category());
|
||||||
|
|
||||||
|
if (Mode == AccessMode::Execute) {
|
||||||
|
// Don't say that directories are executable.
|
||||||
|
struct stat buf;
|
||||||
|
if (0 != stat(P.begin(), &buf))
|
||||||
|
return errc::permission_denied;
|
||||||
|
if (!S_ISREG(buf.st_mode))
|
||||||
|
return errc::permission_denied;
|
||||||
|
}
|
||||||
|
|
||||||
return std::error_code();
|
return std::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_write(const Twine &Path) {
|
|
||||||
SmallString<128> PathStorage;
|
|
||||||
StringRef P = Path.toNullTerminatedStringRef(PathStorage);
|
|
||||||
return 0 == access(P.begin(), W_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool can_execute(const Twine &Path) {
|
|
||||||
SmallString<128> PathStorage;
|
|
||||||
StringRef P = Path.toNullTerminatedStringRef(PathStorage);
|
|
||||||
|
|
||||||
if (0 != access(P.begin(), R_OK | X_OK))
|
|
||||||
return false;
|
|
||||||
struct stat buf;
|
|
||||||
if (0 != stat(P.begin(), &buf))
|
|
||||||
return false;
|
|
||||||
if (!S_ISREG(buf.st_mode))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool equivalent(file_status A, file_status B) {
|
bool equivalent(file_status A, file_status B) {
|
||||||
assert(status_known(A) && status_known(B));
|
assert(status_known(A) && status_known(B));
|
||||||
return A.fs_st_dev == B.fs_st_dev &&
|
return A.fs_st_dev == B.fs_st_dev &&
|
||||||
|
@@ -251,51 +251,31 @@ std::error_code resize_file(const Twine &path, uint64_t size) {
|
|||||||
return std::error_code(error, std::generic_category());
|
return std::error_code(error, std::generic_category());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::error_code exists(const Twine &path, bool &result) {
|
std::error_code access(const Twine &Path, AccessMode Mode) {
|
||||||
SmallString<128> path_storage;
|
SmallString<128> PathStorage;
|
||||||
SmallVector<wchar_t, 128> path_utf16;
|
SmallVector<wchar_t, 128> PathUtf16;
|
||||||
|
|
||||||
if (std::error_code ec =
|
if (std::error_code EC =
|
||||||
UTF8ToUTF16(path.toStringRef(path_storage), path_utf16))
|
UTF8ToUTF16(Path.toStringRef(PathStorage), PathUtf16))
|
||||||
return ec;
|
return EC;
|
||||||
|
|
||||||
DWORD attributes = ::GetFileAttributesW(path_utf16.begin());
|
DWORD Attributes = ::GetFileAttributesW(PathUtf16.begin());
|
||||||
|
|
||||||
if (attributes == INVALID_FILE_ATTRIBUTES) {
|
if (Attributes == INVALID_FILE_ATTRIBUTES) {
|
||||||
// See if the file didn't actually exist.
|
// See if the file didn't actually exist.
|
||||||
DWORD LastError = ::GetLastError();
|
DWORD LastError = ::GetLastError();
|
||||||
if (LastError != ERROR_FILE_NOT_FOUND &&
|
if (LastError != ERROR_FILE_NOT_FOUND &&
|
||||||
LastError != ERROR_PATH_NOT_FOUND)
|
LastError != ERROR_PATH_NOT_FOUND)
|
||||||
return windows_error(LastError);
|
return windows_error(LastError);
|
||||||
result = false;
|
return errc::no_such_file_or_directory;
|
||||||
} else
|
}
|
||||||
result = true;
|
|
||||||
|
if (Mode == AccessMode::Write && (Attributes & FILE_ATTRIBUTE_READONLY))
|
||||||
|
return errc::permission_denied;
|
||||||
|
|
||||||
return std::error_code();
|
return std::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_write(const Twine &Path) {
|
|
||||||
// FIXME: take security attributes into account.
|
|
||||||
SmallString<128> PathStorage;
|
|
||||||
SmallVector<wchar_t, 128> PathUtf16;
|
|
||||||
|
|
||||||
if (UTF8ToUTF16(Path.toStringRef(PathStorage), PathUtf16))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
DWORD Attr = ::GetFileAttributesW(PathUtf16.begin());
|
|
||||||
return (Attr != INVALID_FILE_ATTRIBUTES) && !(Attr & FILE_ATTRIBUTE_READONLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool can_execute(const Twine &Path) {
|
|
||||||
SmallString<128> PathStorage;
|
|
||||||
SmallVector<wchar_t, 128> PathUtf16;
|
|
||||||
|
|
||||||
if (UTF8ToUTF16(Path.toStringRef(PathStorage), PathUtf16))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
DWORD Attr = ::GetFileAttributesW(PathUtf16.begin());
|
|
||||||
return Attr != INVALID_FILE_ATTRIBUTES;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool equivalent(file_status A, file_status B) {
|
bool equivalent(file_status A, file_status B) {
|
||||||
assert(status_known(A) && status_known(B));
|
assert(status_known(A) && status_known(B));
|
||||||
return A.FileIndexHigh == B.FileIndexHigh &&
|
return A.FileIndexHigh == B.FileIndexHigh &&
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/Support/Errc.h"
|
||||||
#include "llvm/Support/FileOutputBuffer.h"
|
#include "llvm/Support/FileOutputBuffer.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/FileSystem.h"
|
#include "llvm/Support/FileSystem.h"
|
||||||
@@ -65,9 +66,8 @@ TEST(FileOutputBuffer, Test) {
|
|||||||
// Do *not* commit buffer.
|
// Do *not* commit buffer.
|
||||||
}
|
}
|
||||||
// Verify file does not exist (because buffer not committed).
|
// Verify file does not exist (because buffer not committed).
|
||||||
bool Exists = false;
|
ASSERT_EQ(fs::access(Twine(File2), fs::AccessMode::Exist),
|
||||||
ASSERT_NO_ERROR(fs::exists(Twine(File2), Exists));
|
errc::no_such_file_or_directory);
|
||||||
EXPECT_FALSE(Exists);
|
|
||||||
ASSERT_NO_ERROR(fs::remove(File2.str()));
|
ASSERT_NO_ERROR(fs::remove(File2.str()));
|
||||||
|
|
||||||
// TEST 3: Verify sizing down case.
|
// TEST 3: Verify sizing down case.
|
||||||
|
@@ -361,9 +361,8 @@ TEST_F(FileSystemTest, TempFiles) {
|
|||||||
EXPECT_EQ(B.type(), fs::file_type::file_not_found);
|
EXPECT_EQ(B.type(), fs::file_type::file_not_found);
|
||||||
|
|
||||||
// Make sure Temp2 doesn't exist.
|
// Make sure Temp2 doesn't exist.
|
||||||
bool TempFileExists;
|
ASSERT_EQ(fs::access(Twine(TempPath2), sys::fs::AccessMode::Exist),
|
||||||
ASSERT_NO_ERROR(fs::exists(Twine(TempPath2), TempFileExists));
|
errc::no_such_file_or_directory);
|
||||||
EXPECT_FALSE(TempFileExists);
|
|
||||||
|
|
||||||
SmallString<64> TempPath3;
|
SmallString<64> TempPath3;
|
||||||
ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "", TempPath3));
|
ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "", TempPath3));
|
||||||
@@ -386,8 +385,8 @@ TEST_F(FileSystemTest, TempFiles) {
|
|||||||
ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
|
ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
|
||||||
|
|
||||||
// Make sure Temp1 doesn't exist.
|
// Make sure Temp1 doesn't exist.
|
||||||
ASSERT_NO_ERROR(fs::exists(Twine(TempPath), TempFileExists));
|
ASSERT_EQ(fs::access(Twine(TempPath), sys::fs::AccessMode::Exist),
|
||||||
EXPECT_FALSE(TempFileExists);
|
errc::no_such_file_or_directory);
|
||||||
|
|
||||||
#ifdef LLVM_ON_WIN32
|
#ifdef LLVM_ON_WIN32
|
||||||
// Path name > 260 chars should get an error.
|
// Path name > 260 chars should get an error.
|
||||||
|
Reference in New Issue
Block a user