aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Host/common/FileSpec.cpp
diff options
context:
space:
mode:
authorPavel Labath <labath@google.com>2017-03-07 13:19:15 +0000
committerPavel Labath <labath@google.com>2017-03-07 13:19:15 +0000
commit30e6cbfcfca4836c2b3497d84ffc2043b548b2a6 (patch)
tree3b24106c96c514a5490b04bfe541e2e6a2ac5518 /lldb/source/Host/common/FileSpec.cpp
parent3d0af578ccc071dc1f9fc1672af55a969e0beb5a (diff)
downloadllvm-30e6cbfcfca4836c2b3497d84ffc2043b548b2a6.zip
llvm-30e6cbfcfca4836c2b3497d84ffc2043b548b2a6.tar.gz
llvm-30e6cbfcfca4836c2b3497d84ffc2043b548b2a6.tar.bz2
Revert "Use LLVM for all stat-related functionality."
this reverts r297116 because it breaks the unittests and TestCompDirSymlink. The ModuleCache unit test is trivially fixable, but the CompDirSymlink failure is a symptom of a deeper problem: llvm's stat functionality is not a drop-in replacement for lldb's. The former is based on stat(2) (which does symlink resolution), while the latter is based on lstat(2) (which does not). This also reverts subsequent build fixes (r297128, r297120, 297117) and r297119 (Remove FileSpec dependency on FileSystem) which builds on top of this. llvm-svn: 297139
Diffstat (limited to 'lldb/source/Host/common/FileSpec.cpp')
-rw-r--r--lldb/source/Host/common/FileSpec.cpp143
1 files changed, 98 insertions, 45 deletions
diff --git a/lldb/source/Host/common/FileSpec.cpp b/lldb/source/Host/common/FileSpec.cpp
index 29fa6d1..10bbea4 100644
--- a/lldb/source/Host/common/FileSpec.cpp
+++ b/lldb/source/Host/common/FileSpec.cpp
@@ -27,6 +27,7 @@
#include "lldb/Core/StringList.h"
#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
@@ -44,18 +45,10 @@ using namespace lldb_private;
namespace {
-static constexpr FileSpec::PathSyntax GetNativeSyntax() {
-#if defined(LLVM_ON_WIN32)
- return FileSpec::ePathSyntaxWindows;
-#else
- return FileSpec::ePathSyntaxPosix;
-#endif
-}
-
bool PathSyntaxIsPosix(FileSpec::PathSyntax syntax) {
return (syntax == FileSpec::ePathSyntaxPosix ||
(syntax == FileSpec::ePathSyntaxHostNative &&
- GetNativeSyntax() == FileSpec::ePathSyntaxPosix));
+ FileSystem::GetNativePathSyntax() == FileSpec::ePathSyntaxPosix));
}
const char *GetPathSeparators(FileSpec::PathSyntax syntax) {
@@ -91,6 +84,13 @@ void Denormalize(llvm::SmallVectorImpl<char> &path,
std::replace(path.begin(), path.end(), '/', '\\');
}
+bool GetFileStats(const FileSpec *file_spec, struct stat *stats_ptr) {
+ char resolved_path[PATH_MAX];
+ if (file_spec->GetPath(resolved_path, sizeof(resolved_path)))
+ return FileSystem::Stat(resolved_path, stats_ptr) == 0;
+ return false;
+}
+
size_t FilenamePos(llvm::StringRef str, FileSpec::PathSyntax syntax) {
if (str.size() == 2 && IsPathSeparator(str[0], syntax) && str[0] == str[1])
return 0;
@@ -273,7 +273,7 @@ void FileSpec::Resolve(llvm::SmallVectorImpl<char> &path) {
}
}
-FileSpec::FileSpec() : m_syntax(GetNativeSyntax()) {}
+FileSpec::FileSpec() : m_syntax(FileSystem::GetNativePathSyntax()) {}
//------------------------------------------------------------------
// Default constructor that can take an optional full path to a
@@ -336,7 +336,9 @@ void FileSpec::SetFile(llvm::StringRef pathname, bool resolve,
m_filename.Clear();
m_directory.Clear();
m_is_resolved = false;
- m_syntax = (syntax == ePathSyntaxHostNative) ? GetNativeSyntax() : syntax;
+ m_syntax = (syntax == ePathSyntaxHostNative)
+ ? FileSystem::GetNativePathSyntax()
+ : syntax;
if (pathname.empty())
return;
@@ -613,10 +615,16 @@ void FileSpec::Dump(Stream *s) const {
//------------------------------------------------------------------
// Returns true if the file exists.
//------------------------------------------------------------------
-bool FileSpec::Exists() const { return llvm::sys::fs::exists(GetPath()); }
+bool FileSpec::Exists() const {
+ struct stat file_stats;
+ return GetFileStats(this, &file_stats);
+}
bool FileSpec::Readable() const {
- return GetPermissions() & llvm::sys::fs::perms::all_read;
+ const uint32_t permissions = GetPermissions();
+ if (permissions & eFilePermissionsEveryoneR)
+ return true;
+ return false;
}
bool FileSpec::ResolveExecutableLocation() {
@@ -669,21 +677,67 @@ bool FileSpec::ResolvePath() {
}
uint64_t FileSpec::GetByteSize() const {
- uint64_t Size = 0;
- if (llvm::sys::fs::file_size(GetPath(), Size))
- return 0;
- return Size;
+ struct stat file_stats;
+ if (GetFileStats(this, &file_stats))
+ return file_stats.st_size;
+ return 0;
}
FileSpec::PathSyntax FileSpec::GetPathSyntax() const { return m_syntax; }
-uint32_t FileSpec::GetPermissions() const {
- namespace fs = llvm::sys::fs;
- fs::file_status st;
- if (fs::status(GetPath(), st))
- return fs::perms::perms_not_known;
+FileSpec::FileType FileSpec::GetFileType() const {
+ struct stat file_stats;
+ if (GetFileStats(this, &file_stats)) {
+ mode_t file_type = file_stats.st_mode & S_IFMT;
+ switch (file_type) {
+ case S_IFDIR:
+ return eFileTypeDirectory;
+ case S_IFREG:
+ return eFileTypeRegular;
+#ifndef _WIN32
+ case S_IFIFO:
+ return eFileTypePipe;
+ case S_IFSOCK:
+ return eFileTypeSocket;
+ case S_IFLNK:
+ return eFileTypeSymbolicLink;
+#endif
+ default:
+ break;
+ }
+ return eFileTypeUnknown;
+ }
+ return eFileTypeInvalid;
+}
+
+bool FileSpec::IsSymbolicLink() const {
+ char resolved_path[PATH_MAX];
+ if (!GetPath(resolved_path, sizeof(resolved_path)))
+ return false;
+
+#ifdef _WIN32
+ std::wstring wpath;
+ if (!llvm::ConvertUTF8toWide(resolved_path, wpath))
+ return false;
+ auto attrs = ::GetFileAttributesW(wpath.c_str());
+ if (attrs == INVALID_FILE_ATTRIBUTES)
+ return false;
- return st.permissions();
+ return (attrs & FILE_ATTRIBUTE_REPARSE_POINT);
+#else
+ struct stat file_stats;
+ if (::lstat(resolved_path, &file_stats) != 0)
+ return false;
+
+ return (file_stats.st_mode & S_IFMT) == S_IFLNK;
+#endif
+}
+
+uint32_t FileSpec::GetPermissions() const {
+ uint32_t file_permissions = 0;
+ if (*this)
+ FileSystem::GetFilePermissions(*this, file_permissions);
+ return file_permissions;
}
//------------------------------------------------------------------
@@ -799,8 +853,7 @@ FileSpec::ForEachItemInDirectory(llvm::StringRef dir_path,
}
do {
- namespace fs = llvm::sys::fs;
- fs::file_type ft = fs::file_type::type_unknown;
+ FileSpec::FileType file_type = eFileTypeUnknown;
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
size_t len = wcslen(ffd.cFileName);
@@ -810,11 +863,11 @@ FileSpec::ForEachItemInDirectory(llvm::StringRef dir_path,
if (len == 2 && ffd.cFileName[0] == L'.' && ffd.cFileName[1] == L'.')
continue;
- ft = fs::file_type::directory_file;
+ file_type = eFileTypeDirectory;
} else if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) {
- ft = fs::file_type::type_unknown;
+ file_type = eFileTypeOther;
} else {
- ft = fs::file_type::regular_file;
+ file_type = eFileTypeRegular;
}
std::string fileName;
@@ -826,7 +879,7 @@ FileSpec::ForEachItemInDirectory(llvm::StringRef dir_path,
// Don't resolve the file type or path
FileSpec child_path_spec(child_path.data(), false);
- EnumerateDirectoryResult result = callback(ft, child_path_spec);
+ EnumerateDirectoryResult result = callback(file_type, child_path_spec);
switch (result) {
case eEnumerateDirectoryResultNext:
@@ -887,38 +940,37 @@ FileSpec::ForEachItemInDirectory(llvm::StringRef dir_path,
continue;
}
- using namespace llvm::sys::fs;
- file_type ft = file_type::type_unknown;
+ FileSpec::FileType file_type = eFileTypeUnknown;
switch (dp->d_type) {
default:
case DT_UNKNOWN:
- ft = file_type::type_unknown;
+ file_type = eFileTypeUnknown;
break;
case DT_FIFO:
- ft = file_type::fifo_file;
+ file_type = eFileTypePipe;
break;
case DT_CHR:
- ft = file_type::character_file;
+ file_type = eFileTypeOther;
break;
case DT_DIR:
- ft = file_type::directory_file;
+ file_type = eFileTypeDirectory;
break;
case DT_BLK:
- ft = file_type::block_file;
+ file_type = eFileTypeOther;
break;
case DT_REG:
- ft = file_type::regular_file;
+ file_type = eFileTypeRegular;
break;
case DT_LNK:
- ft = file_type::symlink_file;
+ file_type = eFileTypeSymbolicLink;
break;
case DT_SOCK:
- ft = file_type::socket_file;
+ file_type = eFileTypeSocket;
break;
#if !defined(__OpenBSD__)
case DT_WHT:
- ft = file_type::type_unknown;
+ file_type = eFileTypeOther;
break;
#endif
}
@@ -933,7 +985,8 @@ FileSpec::ForEachItemInDirectory(llvm::StringRef dir_path,
// Don't resolve the file type or path
FileSpec child_path_spec(child_path, false);
- EnumerateDirectoryResult result = callback(ft, child_path_spec);
+ EnumerateDirectoryResult result =
+ callback(file_type, child_path_spec);
switch (result) {
case eEnumerateDirectoryResultNext:
@@ -987,14 +1040,14 @@ FileSpec::EnumerateDirectory(llvm::StringRef dir_path, bool find_directories,
void *callback_baton) {
return ForEachItemInDirectory(
dir_path,
- [&find_directories, &find_files, &find_other, &callback, &callback_baton](
- llvm::sys::fs::file_type file_type, const FileSpec &file_spec) {
+ [&find_directories, &find_files, &find_other, &callback,
+ &callback_baton](FileType file_type, const FileSpec &file_spec) {
switch (file_type) {
- case llvm::sys::fs::file_type::directory_file:
+ case FileType::eFileTypeDirectory:
if (find_directories)
return callback(callback_baton, file_type, file_spec);
break;
- case llvm::sys::fs::file_type::regular_file:
+ case FileType::eFileTypeRegular:
if (find_files)
return callback(callback_baton, file_type, file_spec);
break;