1 //===-- FileSystem.cpp ------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Host/FileSystem.h" 11 12 #include "lldb/Utility/TildeExpressionResolver.h" 13 14 #include "llvm/Support/FileSystem.h" 15 #include "llvm/Support/Threading.h" 16 17 #include <algorithm> 18 #include <fstream> 19 #include <vector> 20 21 using namespace lldb; 22 using namespace lldb_private; 23 using namespace llvm; 24 25 FileSystem &FileSystem::Instance() { return *InstanceImpl(); } 26 27 void FileSystem::Initialize() { 28 assert(!InstanceImpl()); 29 InstanceImpl().emplace(); 30 } 31 32 void FileSystem::Initialize(IntrusiveRefCntPtr<vfs::FileSystem> fs) { 33 assert(!InstanceImpl()); 34 InstanceImpl().emplace(fs); 35 } 36 37 void FileSystem::Terminate() { 38 assert(InstanceImpl()); 39 InstanceImpl().reset(); 40 } 41 42 Optional<FileSystem> &FileSystem::InstanceImpl() { 43 static Optional<FileSystem> g_fs; 44 return g_fs; 45 } 46 47 void FileSystem::SetFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> fs) { 48 m_fs = fs; 49 } 50 51 sys::TimePoint<> 52 FileSystem::GetModificationTime(const FileSpec &file_spec) const { 53 return GetModificationTime(file_spec.GetPath()); 54 } 55 56 sys::TimePoint<> FileSystem::GetModificationTime(const Twine &path) const { 57 ErrorOr<vfs::Status> status = m_fs->status(path); 58 if (!status) 59 return sys::TimePoint<>(); 60 return status->getLastModificationTime(); 61 } 62 63 uint64_t FileSystem::GetByteSize(const FileSpec &file_spec) const { 64 return GetByteSize(file_spec.GetPath()); 65 } 66 67 uint64_t FileSystem::GetByteSize(const Twine &path) const { 68 ErrorOr<vfs::Status> status = m_fs->status(path); 69 if (!status) 70 return 0; 71 return status->getSize(); 72 } 73 74 uint32_t FileSystem::GetPermissions(const FileSpec &file_spec) const { 75 return GetPermissions(file_spec.GetPath()); 76 } 77 78 uint32_t FileSystem::GetPermissions(const Twine &path) const { 79 ErrorOr<vfs::Status> status = m_fs->status(path); 80 if (!status) 81 return sys::fs::perms::perms_not_known; 82 return status->getPermissions(); 83 } 84 85 bool FileSystem::Exists(const Twine &path) const { return m_fs->exists(path); } 86 87 bool FileSystem::Exists(const FileSpec &file_spec) const { 88 return Exists(file_spec.GetPath()); 89 } 90 91 bool FileSystem::Readable(const Twine &path) const { 92 return GetPermissions(path) & sys::fs::perms::all_read; 93 } 94 95 bool FileSystem::Readable(const FileSpec &file_spec) const { 96 return Readable(file_spec.GetPath()); 97 } 98 99 std::error_code FileSystem::MakeAbsolute(SmallVectorImpl<char> &path) const { 100 return m_fs->makeAbsolute(path); 101 } 102 103 std::error_code FileSystem::MakeAbsolute(FileSpec &file_spec) const { 104 SmallString<128> path; 105 file_spec.GetPath(path, false); 106 107 auto EC = MakeAbsolute(path); 108 if (EC) 109 return EC; 110 111 FileSpec new_file_spec(path, false, file_spec.GetPathStyle()); 112 file_spec = new_file_spec; 113 return {}; 114 } 115 116 std::error_code FileSystem::GetRealPath(const Twine &path, 117 SmallVectorImpl<char> &output) const { 118 return m_fs->getRealPath(path, output); 119 } 120 121 void FileSystem::Resolve(SmallVectorImpl<char> &path) { 122 if (path.empty()) 123 return; 124 125 // Resolve tilde. 126 SmallString<128> original_path(path.begin(), path.end()); 127 StandardTildeExpressionResolver Resolver; 128 Resolver.ResolveFullPath(original_path, path); 129 130 // Try making the path absolute if it exists. 131 SmallString<128> absolute_path(path.begin(), path.end()); 132 MakeAbsolute(path); 133 if (!Exists(path)) { 134 path.clear(); 135 path.append(original_path.begin(), original_path.end()); 136 } 137 } 138 139 void FileSystem::Resolve(FileSpec &file_spec) { 140 // Extract path from the FileSpec. 141 SmallString<128> path; 142 file_spec.GetPath(path); 143 144 // Resolve the path. 145 Resolve(path); 146 147 // Update the FileSpec with the resolved path. 148 file_spec.SetPath(path); 149 } 150