/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Host/common/FileSystem.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- FileSystem.cpp ----------------------------------------------------===// |
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 | | #include "lldb/Host/FileSystem.h" |
10 | | |
11 | | #include "lldb/Utility/DataBufferLLVM.h" |
12 | | |
13 | | #include "llvm/Support/Errc.h" |
14 | | #include "llvm/Support/Errno.h" |
15 | | #include "llvm/Support/Error.h" |
16 | | #include "llvm/Support/FileSystem.h" |
17 | | #include "llvm/Support/Path.h" |
18 | | #include "llvm/Support/Program.h" |
19 | | #include "llvm/Support/Threading.h" |
20 | | |
21 | | #include <cerrno> |
22 | | #include <climits> |
23 | | #include <cstdarg> |
24 | | #include <cstdio> |
25 | | #include <fcntl.h> |
26 | | |
27 | | #ifdef _WIN32 |
28 | | #include "lldb/Host/windows/windows.h" |
29 | | #else |
30 | | #include <sys/ioctl.h> |
31 | | #include <sys/stat.h> |
32 | | #include <termios.h> |
33 | | #include <unistd.h> |
34 | | #endif |
35 | | |
36 | | #include <algorithm> |
37 | | #include <fstream> |
38 | | #include <optional> |
39 | | #include <vector> |
40 | | |
41 | | using namespace lldb; |
42 | | using namespace lldb_private; |
43 | | using namespace llvm; |
44 | | |
45 | 2.01M | FileSystem &FileSystem::Instance() { return *InstanceImpl(); } |
46 | | |
47 | 4.24k | void FileSystem::Terminate() { |
48 | 4.24k | lldbassert(InstanceImpl() && "Already terminated."); |
49 | 4.24k | InstanceImpl().reset(); |
50 | 4.24k | } |
51 | | |
52 | 2.03M | std::optional<FileSystem> &FileSystem::InstanceImpl() { |
53 | 2.03M | static std::optional<FileSystem> g_fs; |
54 | 2.03M | return g_fs; |
55 | 2.03M | } |
56 | | |
57 | | vfs::directory_iterator FileSystem::DirBegin(const FileSpec &file_spec, |
58 | 1 | std::error_code &ec) { |
59 | 1 | if (!file_spec) { |
60 | 1 | ec = std::error_code(static_cast<int>(errc::no_such_file_or_directory), |
61 | 1 | std::system_category()); |
62 | 1 | return {}; |
63 | 1 | } |
64 | 0 | return DirBegin(file_spec.GetPath(), ec); |
65 | 1 | } |
66 | | |
67 | | vfs::directory_iterator FileSystem::DirBegin(const Twine &dir, |
68 | 21 | std::error_code &ec) { |
69 | 21 | return m_fs->dir_begin(dir, ec); |
70 | 21 | } |
71 | | |
72 | | llvm::ErrorOr<vfs::Status> |
73 | 1 | FileSystem::GetStatus(const FileSpec &file_spec) const { |
74 | 1 | if (!file_spec) |
75 | 1 | return std::error_code(static_cast<int>(errc::no_such_file_or_directory), |
76 | 1 | std::system_category()); |
77 | 0 | return GetStatus(file_spec.GetPath()); |
78 | 1 | } |
79 | | |
80 | 325 | llvm::ErrorOr<vfs::Status> FileSystem::GetStatus(const Twine &path) const { |
81 | 325 | return m_fs->status(path); |
82 | 325 | } |
83 | | |
84 | | sys::TimePoint<> |
85 | 41.2k | FileSystem::GetModificationTime(const FileSpec &file_spec) const { |
86 | 41.2k | if (!file_spec) |
87 | 10 | return sys::TimePoint<>(); |
88 | 41.2k | return GetModificationTime(file_spec.GetPath()); |
89 | 41.2k | } |
90 | | |
91 | 41.2k | sys::TimePoint<> FileSystem::GetModificationTime(const Twine &path) const { |
92 | 41.2k | ErrorOr<vfs::Status> status = m_fs->status(path); |
93 | 41.2k | if (!status) |
94 | 4.83k | return sys::TimePoint<>(); |
95 | 36.3k | return status->getLastModificationTime(); |
96 | 41.2k | } |
97 | | |
98 | 605k | uint64_t FileSystem::GetByteSize(const FileSpec &file_spec) const { |
99 | 605k | if (!file_spec) |
100 | 47 | return 0; |
101 | 605k | return GetByteSize(file_spec.GetPath()); |
102 | 605k | } |
103 | | |
104 | 605k | uint64_t FileSystem::GetByteSize(const Twine &path) const { |
105 | 605k | ErrorOr<vfs::Status> status = m_fs->status(path); |
106 | 605k | if (!status) |
107 | 2.30k | return 0; |
108 | 602k | return status->getSize(); |
109 | 605k | } |
110 | | |
111 | 51 | uint32_t FileSystem::GetPermissions(const FileSpec &file_spec) const { |
112 | 51 | return GetPermissions(file_spec.GetPath()); |
113 | 51 | } |
114 | | |
115 | | uint32_t FileSystem::GetPermissions(const FileSpec &file_spec, |
116 | 0 | std::error_code &ec) const { |
117 | 0 | if (!file_spec) |
118 | 0 | return sys::fs::perms::perms_not_known; |
119 | 0 | return GetPermissions(file_spec.GetPath(), ec); |
120 | 0 | } |
121 | | |
122 | 57 | uint32_t FileSystem::GetPermissions(const Twine &path) const { |
123 | 57 | std::error_code ec; |
124 | 57 | return GetPermissions(path, ec); |
125 | 57 | } |
126 | | |
127 | | uint32_t FileSystem::GetPermissions(const Twine &path, |
128 | 57 | std::error_code &ec) const { |
129 | 57 | ErrorOr<vfs::Status> status = m_fs->status(path); |
130 | 57 | if (!status) { |
131 | 48 | ec = status.getError(); |
132 | 48 | return sys::fs::perms::perms_not_known; |
133 | 48 | } |
134 | 9 | return status->getPermissions(); |
135 | 57 | } |
136 | | |
137 | 991k | bool FileSystem::Exists(const Twine &path) const { return m_fs->exists(path); } |
138 | | |
139 | 489k | bool FileSystem::Exists(const FileSpec &file_spec) const { |
140 | 489k | return file_spec && Exists(file_spec.GetPath())475k ; |
141 | 489k | } |
142 | | |
143 | 5 | bool FileSystem::Readable(const Twine &path) const { |
144 | 5 | return GetPermissions(path) & sys::fs::perms::all_read; |
145 | 5 | } |
146 | | |
147 | 4 | bool FileSystem::Readable(const FileSpec &file_spec) const { |
148 | 4 | return file_spec && Readable(file_spec.GetPath())3 ; |
149 | 4 | } |
150 | | |
151 | 130k | bool FileSystem::IsDirectory(const Twine &path) const { |
152 | 130k | ErrorOr<vfs::Status> status = m_fs->status(path); |
153 | 130k | if (!status) |
154 | 593 | return false; |
155 | 129k | return status->isDirectory(); |
156 | 130k | } |
157 | | |
158 | 126k | bool FileSystem::IsDirectory(const FileSpec &file_spec) const { |
159 | 126k | return file_spec && IsDirectory(file_spec.GetPath())126k ; |
160 | 126k | } |
161 | | |
162 | 63.7k | bool FileSystem::IsLocal(const Twine &path) const { |
163 | 63.7k | bool b = false; |
164 | 63.7k | m_fs->isLocal(path, b); |
165 | 63.7k | return b; |
166 | 63.7k | } |
167 | | |
168 | 1 | bool FileSystem::IsLocal(const FileSpec &file_spec) const { |
169 | 1 | return file_spec && IsLocal(file_spec.GetPath())0 ; |
170 | 1 | } |
171 | | |
172 | | void FileSystem::EnumerateDirectory(Twine path, bool find_directories, |
173 | | bool find_files, bool find_other, |
174 | | EnumerateDirectoryCallbackType callback, |
175 | 2.05k | void *callback_baton) { |
176 | 2.05k | std::error_code EC; |
177 | 2.05k | vfs::recursive_directory_iterator Iter(*m_fs, path, EC); |
178 | 2.05k | vfs::recursive_directory_iterator End; |
179 | 2.59k | for (; Iter != End && !EC539 ; Iter.increment(EC)539 ) { |
180 | 539 | const auto &Item = *Iter; |
181 | 539 | ErrorOr<vfs::Status> Status = m_fs->status(Item.path()); |
182 | 539 | if (!Status) |
183 | 1 | continue; |
184 | 538 | if (!find_files && Status->isRegularFile()534 ) |
185 | 0 | continue; |
186 | 538 | if (!find_directories && Status->isDirectory()0 ) |
187 | 0 | continue; |
188 | 538 | if (!find_other && Status->isOther()81 ) |
189 | 0 | continue; |
190 | | |
191 | 538 | auto Result = callback(callback_baton, Status->getType(), Item.path()); |
192 | 538 | if (Result == eEnumerateDirectoryResultQuit) |
193 | 0 | return; |
194 | 538 | if (Result == eEnumerateDirectoryResultNext) { |
195 | | // Default behavior is to recurse. Opt out if the callback doesn't want |
196 | | // this behavior. |
197 | 538 | Iter.no_push(); |
198 | 538 | } |
199 | 538 | } |
200 | 2.05k | } |
201 | | |
202 | 513k | std::error_code FileSystem::MakeAbsolute(SmallVectorImpl<char> &path) const { |
203 | 513k | return m_fs->makeAbsolute(path); |
204 | 513k | } |
205 | | |
206 | 1 | std::error_code FileSystem::MakeAbsolute(FileSpec &file_spec) const { |
207 | 1 | SmallString<128> path; |
208 | 1 | file_spec.GetPath(path, false); |
209 | | |
210 | 1 | auto EC = MakeAbsolute(path); |
211 | 1 | if (EC) |
212 | 0 | return EC; |
213 | | |
214 | 1 | FileSpec new_file_spec(path, file_spec.GetPathStyle()); |
215 | 1 | file_spec = new_file_spec; |
216 | 1 | return {}; |
217 | 1 | } |
218 | | |
219 | | std::error_code FileSystem::GetRealPath(const Twine &path, |
220 | 0 | SmallVectorImpl<char> &output) const { |
221 | 0 | return m_fs->getRealPath(path, output); |
222 | 0 | } |
223 | | |
224 | 513k | void FileSystem::Resolve(SmallVectorImpl<char> &path) { |
225 | 513k | if (path.empty()) |
226 | 0 | return; |
227 | | |
228 | | // Resolve tilde in path. |
229 | 513k | SmallString<128> resolved(path.begin(), path.end()); |
230 | 513k | assert(m_tilde_resolver && "must initialize tilde resolver in constructor"); |
231 | 513k | m_tilde_resolver->ResolveFullPath(llvm::StringRef(path.begin(), path.size()), |
232 | 513k | resolved); |
233 | | |
234 | | // Try making the path absolute if it exists. |
235 | 513k | SmallString<128> absolute(resolved.begin(), resolved.end()); |
236 | 513k | MakeAbsolute(absolute); |
237 | | |
238 | 513k | path.clear(); |
239 | 513k | if (Exists(absolute)) { |
240 | 368k | path.append(absolute.begin(), absolute.end()); |
241 | 368k | } else { |
242 | 145k | path.append(resolved.begin(), resolved.end()); |
243 | 145k | } |
244 | 513k | } |
245 | | |
246 | 519k | void FileSystem::Resolve(FileSpec &file_spec) { |
247 | 519k | if (!file_spec) |
248 | 6.22k | return; |
249 | | |
250 | | // Extract path from the FileSpec. |
251 | 513k | SmallString<128> path; |
252 | 513k | file_spec.GetPath(path); |
253 | | |
254 | | // Resolve the path. |
255 | 513k | Resolve(path); |
256 | | |
257 | | // Update the FileSpec with the resolved path. |
258 | 513k | if (file_spec.GetFilename().IsEmpty()) |
259 | 813 | file_spec.SetDirectory(path); |
260 | 512k | else |
261 | 512k | file_spec.SetPath(path); |
262 | 513k | file_spec.SetIsResolved(true); |
263 | 513k | } |
264 | | |
265 | | template <typename T> |
266 | | static std::unique_ptr<T> GetMemoryBuffer(const llvm::Twine &path, |
267 | | uint64_t size, uint64_t offset, |
268 | 63.7k | bool is_volatile) { |
269 | 63.7k | std::unique_ptr<T> buffer; |
270 | 63.7k | if (size == 0) { |
271 | 3.75k | auto buffer_or_error = T::getFile(path, is_volatile); |
272 | 3.75k | if (!buffer_or_error) |
273 | 0 | return nullptr; |
274 | 3.75k | buffer = std::move(*buffer_or_error); |
275 | 60.0k | } else { |
276 | 60.0k | auto buffer_or_error = T::getFileSlice(path, size, offset, is_volatile); |
277 | 60.0k | if (!buffer_or_error) |
278 | 1.96k | return nullptr; |
279 | 58.0k | buffer = std::move(*buffer_or_error); |
280 | 58.0k | } |
281 | 61.8k | return buffer; |
282 | 63.7k | } FileSystem.cpp:std::__1::unique_ptr<llvm::WritableMemoryBuffer, std::__1::default_delete<llvm::WritableMemoryBuffer> > GetMemoryBuffer<llvm::WritableMemoryBuffer>(llvm::Twine const&, unsigned long long, unsigned long long, bool) Line | Count | Source | 268 | 2.46k | bool is_volatile) { | 269 | 2.46k | std::unique_ptr<T> buffer; | 270 | 2.46k | if (size == 0) { | 271 | 2.08k | auto buffer_or_error = T::getFile(path, is_volatile); | 272 | 2.08k | if (!buffer_or_error) | 273 | 0 | return nullptr; | 274 | 2.08k | buffer = std::move(*buffer_or_error); | 275 | 2.08k | } else { | 276 | 374 | auto buffer_or_error = T::getFileSlice(path, size, offset, is_volatile); | 277 | 374 | if (!buffer_or_error) | 278 | 0 | return nullptr; | 279 | 374 | buffer = std::move(*buffer_or_error); | 280 | 374 | } | 281 | 2.46k | return buffer; | 282 | 2.46k | } |
FileSystem.cpp:std::__1::unique_ptr<llvm::MemoryBuffer, std::__1::default_delete<llvm::MemoryBuffer> > GetMemoryBuffer<llvm::MemoryBuffer>(llvm::Twine const&, unsigned long long, unsigned long long, bool) Line | Count | Source | 268 | 61.3k | bool is_volatile) { | 269 | 61.3k | std::unique_ptr<T> buffer; | 270 | 61.3k | if (size == 0) { | 271 | 1.66k | auto buffer_or_error = T::getFile(path, is_volatile); | 272 | 1.66k | if (!buffer_or_error) | 273 | 0 | return nullptr; | 274 | 1.66k | buffer = std::move(*buffer_or_error); | 275 | 59.6k | } else { | 276 | 59.6k | auto buffer_or_error = T::getFileSlice(path, size, offset, is_volatile); | 277 | 59.6k | if (!buffer_or_error) | 278 | 1.96k | return nullptr; | 279 | 57.7k | buffer = std::move(*buffer_or_error); | 280 | 57.7k | } | 281 | 59.3k | return buffer; | 282 | 61.3k | } |
|
283 | | |
284 | | std::shared_ptr<WritableDataBuffer> |
285 | | FileSystem::CreateWritableDataBuffer(const llvm::Twine &path, uint64_t size, |
286 | 2.46k | uint64_t offset) { |
287 | 2.46k | const bool is_volatile = !IsLocal(path); |
288 | 2.46k | auto buffer = GetMemoryBuffer<llvm::WritableMemoryBuffer>(path, size, offset, |
289 | 2.46k | is_volatile); |
290 | 2.46k | if (!buffer) |
291 | 0 | return {}; |
292 | 2.46k | return std::shared_ptr<WritableDataBufferLLVM>( |
293 | 2.46k | new WritableDataBufferLLVM(std::move(buffer))); |
294 | 2.46k | } |
295 | | |
296 | | std::shared_ptr<DataBuffer> |
297 | | FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size, |
298 | 61.3k | uint64_t offset) { |
299 | 61.3k | const bool is_volatile = !IsLocal(path); |
300 | 61.3k | auto buffer = |
301 | 61.3k | GetMemoryBuffer<llvm::MemoryBuffer>(path, size, offset, is_volatile); |
302 | 61.3k | if (!buffer) |
303 | 1.96k | return {}; |
304 | 59.3k | return std::shared_ptr<DataBufferLLVM>(new DataBufferLLVM(std::move(buffer))); |
305 | 61.3k | } |
306 | | |
307 | | std::shared_ptr<WritableDataBuffer> |
308 | | FileSystem::CreateWritableDataBuffer(const FileSpec &file_spec, uint64_t size, |
309 | 2.08k | uint64_t offset) { |
310 | 2.08k | return CreateWritableDataBuffer(file_spec.GetPath(), size, offset); |
311 | 2.08k | } |
312 | | |
313 | | std::shared_ptr<DataBuffer> |
314 | | FileSystem::CreateDataBuffer(const FileSpec &file_spec, uint64_t size, |
315 | 1.68k | uint64_t offset) { |
316 | 1.68k | return CreateDataBuffer(file_spec.GetPath(), size, offset); |
317 | 1.68k | } |
318 | | |
319 | 750 | bool FileSystem::ResolveExecutableLocation(FileSpec &file_spec) { |
320 | | // If the directory is set there's nothing to do. |
321 | 750 | ConstString directory = file_spec.GetDirectory(); |
322 | 750 | if (directory) |
323 | 698 | return false; |
324 | | |
325 | | // We cannot look for a file if there's no file name. |
326 | 52 | ConstString filename = file_spec.GetFilename(); |
327 | 52 | if (!filename) |
328 | 47 | return false; |
329 | | |
330 | | // Search for the file on the host. |
331 | 5 | const std::string filename_str(filename.GetCString()); |
332 | 5 | llvm::ErrorOr<std::string> error_or_path = |
333 | 5 | llvm::sys::findProgramByName(filename_str); |
334 | 5 | if (!error_or_path) |
335 | 4 | return false; |
336 | | |
337 | | // findProgramByName returns "." if it can't find the file. |
338 | 1 | llvm::StringRef path = *error_or_path; |
339 | 1 | llvm::StringRef parent = llvm::sys::path::parent_path(path); |
340 | 1 | if (parent.empty() || parent == ".") |
341 | 0 | return false; |
342 | | |
343 | | // Make sure that the result exists. |
344 | 1 | FileSpec result(*error_or_path); |
345 | 1 | if (!Exists(result)) |
346 | 0 | return false; |
347 | | |
348 | 1 | file_spec = result; |
349 | 1 | return true; |
350 | 1 | } |
351 | | |
352 | 3.93k | bool FileSystem::GetHomeDirectory(SmallVectorImpl<char> &path) const { |
353 | 3.93k | if (!m_home_directory.empty()) { |
354 | 0 | path.assign(m_home_directory.begin(), m_home_directory.end()); |
355 | 0 | return true; |
356 | 0 | } |
357 | 3.93k | return llvm::sys::path::home_directory(path); |
358 | 3.93k | } |
359 | | |
360 | 0 | bool FileSystem::GetHomeDirectory(FileSpec &file_spec) const { |
361 | 0 | SmallString<128> home_dir; |
362 | 0 | if (!GetHomeDirectory(home_dir)) |
363 | 0 | return false; |
364 | 0 | file_spec.SetPath(home_dir); |
365 | 0 | return true; |
366 | 0 | } |
367 | | |
368 | | static int OpenWithFS(const FileSystem &fs, const char *path, int flags, |
369 | 12.6k | int mode) { |
370 | 12.6k | return const_cast<FileSystem &>(fs).Open(path, flags, mode); |
371 | 12.6k | } |
372 | | |
373 | 12.6k | static int GetOpenFlags(File::OpenOptions options) { |
374 | 12.6k | int open_flags = 0; |
375 | 12.6k | File::OpenOptions rw = |
376 | 12.6k | options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly | |
377 | 12.6k | File::eOpenOptionReadWrite); |
378 | 12.6k | if (rw == File::eOpenOptionWriteOnly || rw == File::eOpenOptionReadWrite6.76k ) { |
379 | 5.84k | if (rw == File::eOpenOptionReadWrite) |
380 | 0 | open_flags |= O_RDWR; |
381 | 5.84k | else |
382 | 5.84k | open_flags |= O_WRONLY; |
383 | | |
384 | 5.84k | if (options & File::eOpenOptionAppend) |
385 | 4 | open_flags |= O_APPEND; |
386 | | |
387 | 5.84k | if (options & File::eOpenOptionTruncate) |
388 | 55 | open_flags |= O_TRUNC; |
389 | | |
390 | 5.84k | if (options & File::eOpenOptionCanCreate) |
391 | 77 | open_flags |= O_CREAT; |
392 | | |
393 | 5.84k | if (options & File::eOpenOptionCanCreateNewOnly) |
394 | 0 | open_flags |= O_CREAT | O_EXCL; |
395 | 6.76k | } else if (rw == File::eOpenOptionReadOnly) { |
396 | 6.76k | open_flags |= O_RDONLY; |
397 | | |
398 | 6.76k | #ifndef _WIN32 |
399 | 6.76k | if (options & File::eOpenOptionDontFollowSymlinks) |
400 | 0 | open_flags |= O_NOFOLLOW; |
401 | 6.76k | #endif |
402 | 6.76k | } |
403 | | |
404 | 12.6k | #ifndef _WIN32 |
405 | 12.6k | if (options & File::eOpenOptionNonBlocking) |
406 | 0 | open_flags |= O_NONBLOCK; |
407 | 12.6k | if (options & File::eOpenOptionCloseOnExec) |
408 | 33 | open_flags |= O_CLOEXEC; |
409 | | #else |
410 | | open_flags |= O_BINARY; |
411 | | #endif |
412 | | |
413 | 12.6k | return open_flags; |
414 | 12.6k | } |
415 | | |
416 | 77 | static mode_t GetOpenMode(uint32_t permissions) { |
417 | 77 | mode_t mode = 0; |
418 | 77 | if (permissions & lldb::eFilePermissionsUserRead) |
419 | 77 | mode |= S_IRUSR; |
420 | 77 | if (permissions & lldb::eFilePermissionsUserWrite) |
421 | 77 | mode |= S_IWUSR; |
422 | 77 | if (permissions & lldb::eFilePermissionsUserExecute) |
423 | 0 | mode |= S_IXUSR; |
424 | 77 | if (permissions & lldb::eFilePermissionsGroupRead) |
425 | 1 | mode |= S_IRGRP; |
426 | 77 | if (permissions & lldb::eFilePermissionsGroupWrite) |
427 | 0 | mode |= S_IWGRP; |
428 | 77 | if (permissions & lldb::eFilePermissionsGroupExecute) |
429 | 0 | mode |= S_IXGRP; |
430 | 77 | if (permissions & lldb::eFilePermissionsWorldRead) |
431 | 1 | mode |= S_IROTH; |
432 | 77 | if (permissions & lldb::eFilePermissionsWorldWrite) |
433 | 0 | mode |= S_IWOTH; |
434 | 77 | if (permissions & lldb::eFilePermissionsWorldExecute) |
435 | 0 | mode |= S_IXOTH; |
436 | 77 | return mode; |
437 | 77 | } |
438 | | |
439 | | Expected<FileUP> FileSystem::Open(const FileSpec &file_spec, |
440 | | File::OpenOptions options, |
441 | 12.6k | uint32_t permissions, bool should_close_fd) { |
442 | 12.6k | const int open_flags = GetOpenFlags(options); |
443 | 12.6k | const mode_t open_mode = |
444 | 12.6k | (open_flags & O_CREAT) ? GetOpenMode(permissions)77 : 012.5k ; |
445 | | |
446 | 12.6k | auto path = file_spec.GetPath(); |
447 | | |
448 | 12.6k | int descriptor = llvm::sys::RetryAfterSignal( |
449 | 12.6k | -1, OpenWithFS, *this, path.c_str(), open_flags, open_mode); |
450 | | |
451 | 12.6k | if (!File::DescriptorIsValid(descriptor)) |
452 | 7 | return llvm::errorCodeToError( |
453 | 7 | std::error_code(errno, std::system_category())); |
454 | | |
455 | 12.6k | auto file = std::unique_ptr<File>( |
456 | 12.6k | new NativeFile(descriptor, options, should_close_fd)); |
457 | 12.6k | assert(file->IsValid()); |
458 | 12.6k | return std::move(file); |
459 | 12.6k | } |
460 | | |
461 | 0 | void FileSystem::SetHomeDirectory(std::string home_directory) { |
462 | 0 | m_home_directory = std::move(home_directory); |
463 | 0 | } |
464 | | |
465 | 1 | Status FileSystem::RemoveFile(const FileSpec &file_spec) { |
466 | 1 | return RemoveFile(file_spec.GetPath()); |
467 | 1 | } |
468 | | |
469 | 1 | Status FileSystem::RemoveFile(const llvm::Twine &path) { |
470 | 1 | return Status(llvm::sys::fs::remove(path)); |
471 | 1 | } |