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