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
28namespace lldb_private {
29class FileSystem {
30public:
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_home_directory(), m_mapped(false) {}
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)
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
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
199private:
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