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