1 //===-- FileSystem.h --------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_HOST_FILESYSTEM_H 10 #define LLDB_HOST_FILESYSTEM_H 11 12 #include "lldb/Host/File.h" 13 #include "lldb/Utility/DataBufferLLVM.h" 14 #include "lldb/Utility/FileSpec.h" 15 #include "lldb/Utility/Status.h" 16 17 #include "llvm/ADT/Optional.h" 18 #include "llvm/Support/Chrono.h" 19 #include "llvm/Support/FileCollector.h" 20 #include "llvm/Support/VirtualFileSystem.h" 21 22 #include "lldb/lldb-types.h" 23 24 #include <cstdint> 25 #include <cstdio> 26 #include <sys/stat.h> 27 28 namespace lldb_private { 29 class FileSystem { 30 public: 31 static const char *DEV_NULL; 32 static const char *PATH_CONVERSION_ERROR; 33 34 FileSystem() : m_fs(llvm::vfs::getRealFileSystem()), m_collector(nullptr) {} 35 FileSystem(std::shared_ptr<llvm::FileCollectorBase> collector) 36 : m_fs(llvm::vfs::getRealFileSystem()), m_collector(std::move(collector)), 37 m_mapped(false) {} 38 FileSystem(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs, 39 bool mapped = false) 40 : m_fs(std::move(fs)), m_collector(nullptr), m_mapped(mapped) {} 41 42 FileSystem(const FileSystem &fs) = delete; 43 FileSystem &operator=(const FileSystem &fs) = delete; 44 45 static FileSystem &Instance(); 46 47 static void Initialize(); 48 static void Initialize(std::shared_ptr<llvm::FileCollectorBase> collector); 49 static llvm::Error Initialize(const FileSpec &mapping); 50 static void Initialize(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> fs); 51 static void Terminate(); 52 53 Status Symlink(const FileSpec &src, const FileSpec &dst); 54 Status Readlink(const FileSpec &src, FileSpec &dst); 55 56 Status ResolveSymbolicLink(const FileSpec &src, FileSpec &dst); 57 58 /// Wraps ::fopen in a platform-independent way. 59 FILE *Fopen(const char *path, const char *mode); 60 61 /// Wraps ::open in a platform-independent way. 62 int Open(const char *path, int flags, int mode); 63 64 llvm::Expected<std::unique_ptr<File>> 65 Open(const FileSpec &file_spec, File::OpenOptions options, 66 uint32_t permissions = lldb::eFilePermissionsFileDefault, 67 bool should_close_fd = true); 68 69 /// Get a directory iterator. 70 /// \{ 71 llvm::vfs::directory_iterator DirBegin(const FileSpec &file_spec, 72 std::error_code &ec); 73 llvm::vfs::directory_iterator DirBegin(const llvm::Twine &dir, 74 std::error_code &ec); 75 /// \} 76 77 /// Returns the Status object for the given file. 78 /// \{ 79 llvm::ErrorOr<llvm::vfs::Status> GetStatus(const FileSpec &file_spec) const; 80 llvm::ErrorOr<llvm::vfs::Status> GetStatus(const llvm::Twine &path) const; 81 /// \} 82 83 /// Returns the modification time of the given file. 84 /// \{ 85 llvm::sys::TimePoint<> GetModificationTime(const FileSpec &file_spec) const; 86 llvm::sys::TimePoint<> GetModificationTime(const llvm::Twine &path) const; 87 /// \} 88 89 /// Returns the on-disk size of the given file in bytes. 90 /// \{ 91 uint64_t GetByteSize(const FileSpec &file_spec) const; 92 uint64_t GetByteSize(const llvm::Twine &path) const; 93 /// \} 94 95 /// Return the current permissions of the given file. 96 /// 97 /// Returns a bitmask for the current permissions of the file (zero or more 98 /// of the permission bits defined in File::Permissions). 99 /// \{ 100 uint32_t GetPermissions(const FileSpec &file_spec) const; 101 uint32_t GetPermissions(const llvm::Twine &path) const; 102 uint32_t GetPermissions(const FileSpec &file_spec, std::error_code &ec) const; 103 uint32_t GetPermissions(const llvm::Twine &path, std::error_code &ec) const; 104 /// \} 105 106 /// Returns whether the given file exists. 107 /// \{ 108 bool Exists(const FileSpec &file_spec) const; 109 bool Exists(const llvm::Twine &path) const; 110 /// \} 111 112 /// Returns whether the given file is readable. 113 /// \{ 114 bool Readable(const FileSpec &file_spec) const; 115 bool Readable(const llvm::Twine &path) const; 116 /// \} 117 118 /// Returns whether the given path is a directory. 119 /// \{ 120 bool IsDirectory(const FileSpec &file_spec) const; 121 bool IsDirectory(const llvm::Twine &path) const; 122 /// \} 123 124 /// Returns whether the given path is local to the file system. 125 /// \{ 126 bool IsLocal(const FileSpec &file_spec) const; 127 bool IsLocal(const llvm::Twine &path) const; 128 /// \} 129 130 /// Make the given file path absolute. 131 /// \{ 132 std::error_code MakeAbsolute(llvm::SmallVectorImpl<char> &path) const; 133 std::error_code MakeAbsolute(FileSpec &file_spec) const; 134 /// \} 135 136 /// Resolve path to make it canonical. 137 /// \{ 138 void Resolve(llvm::SmallVectorImpl<char> &path); 139 void Resolve(FileSpec &file_spec); 140 /// \} 141 142 /// Remove a single file. 143 /// 144 /// The path must specify a file and not a directory. 145 /// \{ 146 Status RemoveFile(const FileSpec &file_spec); 147 Status RemoveFile(const llvm::Twine &path); 148 /// \} 149 150 //// Create memory buffer from path. 151 /// \{ 152 std::shared_ptr<DataBufferLLVM> CreateDataBuffer(const llvm::Twine &path, 153 uint64_t size = 0, 154 uint64_t offset = 0); 155 std::shared_ptr<DataBufferLLVM> CreateDataBuffer(const FileSpec &file_spec, 156 uint64_t size = 0, 157 uint64_t offset = 0); 158 /// \} 159 160 /// Call into the Host to see if it can help find the file. 161 bool ResolveExecutableLocation(FileSpec &file_spec); 162 163 /// Get the user home directory. 164 bool GetHomeDirectory(llvm::SmallVectorImpl<char> &path) const; 165 bool GetHomeDirectory(FileSpec &file_spec) const; 166 167 enum EnumerateDirectoryResult { 168 /// Enumerate next entry in the current directory. 169 eEnumerateDirectoryResultNext, 170 /// Recurse into the current entry if it is a directory or symlink, or next 171 /// if not. 172 eEnumerateDirectoryResultEnter, 173 /// Stop directory enumerations at any level. 174 eEnumerateDirectoryResultQuit 175 }; 176 177 typedef EnumerateDirectoryResult (*EnumerateDirectoryCallbackType)( 178 void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef); 179 180 typedef std::function<EnumerateDirectoryResult( 181 llvm::sys::fs::file_type file_type, llvm::StringRef)> 182 DirectoryCallback; 183 184 void EnumerateDirectory(llvm::Twine path, bool find_directories, 185 bool find_files, bool find_other, 186 EnumerateDirectoryCallbackType callback, 187 void *callback_baton); 188 189 std::error_code GetRealPath(const llvm::Twine &path, 190 llvm::SmallVectorImpl<char> &output) const; 191 192 llvm::ErrorOr<std::string> GetExternalPath(const llvm::Twine &path); 193 llvm::ErrorOr<std::string> GetExternalPath(const FileSpec &file_spec); 194 195 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> GetVirtualFileSystem() { 196 return m_fs; 197 } 198 199 void Collect(const FileSpec &file_spec); 200 void Collect(const llvm::Twine &file); 201 202 void SetHomeDirectory(std::string home_directory); 203 204 private: 205 static llvm::Optional<FileSystem> &InstanceImpl(); 206 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> m_fs; 207 std::shared_ptr<llvm::FileCollectorBase> m_collector; 208 std::string m_home_directory; 209 bool m_mapped = false; 210 }; 211 } // namespace lldb_private 212 213 #endif 214