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