1 //===- llvm/Support/FileSystem.h - File System OS Concept -------*- 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 // This file declares the llvm::sys::fs namespace. It is designed after 10 // TR2/boost filesystem (v3), but modified to remove exception handling and the 11 // path class. 12 // 13 // All functions return an error_code and their actual work via the last out 14 // argument. The out argument is defined if and only if errc::success is 15 // returned. A function may return any error code in the generic or system 16 // category. However, they shall be equivalent to any error conditions listed 17 // in each functions respective documentation if the condition applies. [ note: 18 // this does not guarantee that error_code will be in the set of explicitly 19 // listed codes, but it does guarantee that if any of the explicitly listed 20 // errors occur, the correct error_code will be used ]. All functions may 21 // return errc::not_enough_memory if there is not enough memory to complete the 22 // operation. 23 // 24 //===----------------------------------------------------------------------===// 25 26 #ifndef LLVM_SUPPORT_FILESYSTEM_H 27 #define LLVM_SUPPORT_FILESYSTEM_H 28 29 #include "llvm/ADT/SmallString.h" 30 #include "llvm/ADT/StringRef.h" 31 #include "llvm/ADT/Twine.h" 32 #include "llvm/Config/llvm-config.h" 33 #include "llvm/Support/Chrono.h" 34 #include "llvm/Support/Error.h" 35 #include "llvm/Support/ErrorHandling.h" 36 #include "llvm/Support/ErrorOr.h" 37 #include "llvm/Support/FileSystem/UniqueID.h" 38 #include "llvm/Support/MD5.h" 39 #include <cassert> 40 #include <cstdint> 41 #include <ctime> 42 #include <memory> 43 #include <string> 44 #include <system_error> 45 #include <vector> 46 47 #ifdef HAVE_SYS_STAT_H 48 #include <sys/stat.h> 49 #endif 50 51 namespace llvm { 52 namespace sys { 53 namespace fs { 54 55 #if defined(_WIN32) 56 // A Win32 HANDLE is a typedef of void* 57 using file_t = void *; 58 #else 59 using file_t = int; 60 #endif 61 62 extern const file_t kInvalidFile; 63 64 /// An enumeration for the file system's view of the type. 65 enum class file_type { 66 status_error, 67 file_not_found, 68 regular_file, 69 directory_file, 70 symlink_file, 71 block_file, 72 character_file, 73 fifo_file, 74 socket_file, 75 type_unknown 76 }; 77 78 /// space_info - Self explanatory. 79 struct space_info { 80 uint64_t capacity; 81 uint64_t free; 82 uint64_t available; 83 }; 84 85 enum perms { 86 no_perms = 0, 87 owner_read = 0400, 88 owner_write = 0200, 89 owner_exe = 0100, 90 owner_all = owner_read | owner_write | owner_exe, 91 group_read = 040, 92 group_write = 020, 93 group_exe = 010, 94 group_all = group_read | group_write | group_exe, 95 others_read = 04, 96 others_write = 02, 97 others_exe = 01, 98 others_all = others_read | others_write | others_exe, 99 all_read = owner_read | group_read | others_read, 100 all_write = owner_write | group_write | others_write, 101 all_exe = owner_exe | group_exe | others_exe, 102 all_all = owner_all | group_all | others_all, 103 set_uid_on_exe = 04000, 104 set_gid_on_exe = 02000, 105 sticky_bit = 01000, 106 all_perms = all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit, 107 perms_not_known = 0xFFFF 108 }; 109 110 // Helper functions so that you can use & and | to manipulate perms bits: 111 inline perms operator|(perms l, perms r) { 112 return static_cast<perms>(static_cast<unsigned short>(l) | 113 static_cast<unsigned short>(r)); 114 } 115 inline perms operator&(perms l, perms r) { 116 return static_cast<perms>(static_cast<unsigned short>(l) & 117 static_cast<unsigned short>(r)); 118 } 119 inline perms &operator|=(perms &l, perms r) { 120 l = l | r; 121 return l; 122 } 123 inline perms &operator&=(perms &l, perms r) { 124 l = l & r; 125 return l; 126 } 127 inline perms operator~(perms x) { 128 // Avoid UB by explicitly truncating the (unsigned) ~ result. 129 return static_cast<perms>( 130 static_cast<unsigned short>(~static_cast<unsigned short>(x))); 131 } 132 133 /// Represents the result of a call to directory_iterator::status(). This is a 134 /// subset of the information returned by a regular sys::fs::status() call, and 135 /// represents the information provided by Windows FileFirstFile/FindNextFile. 136 class basic_file_status { 137 protected: 138 #if defined(LLVM_ON_UNIX) 139 time_t fs_st_atime = 0; 140 time_t fs_st_mtime = 0; 141 uint32_t fs_st_atime_nsec = 0; 142 uint32_t fs_st_mtime_nsec = 0; 143 uid_t fs_st_uid = 0; 144 gid_t fs_st_gid = 0; 145 off_t fs_st_size = 0; 146 #elif defined (_WIN32) 147 uint32_t LastAccessedTimeHigh = 0; 148 uint32_t LastAccessedTimeLow = 0; 149 uint32_t LastWriteTimeHigh = 0; 150 uint32_t LastWriteTimeLow = 0; 151 uint32_t FileSizeHigh = 0; 152 uint32_t FileSizeLow = 0; 153 #endif 154 file_type Type = file_type::status_error; 155 perms Perms = perms_not_known; 156 157 public: 158 basic_file_status() = default; 159 160 explicit basic_file_status(file_type Type) : Type(Type) {} 161 162 #if defined(LLVM_ON_UNIX) 163 basic_file_status(file_type Type, perms Perms, time_t ATime, 164 uint32_t ATimeNSec, time_t MTime, uint32_t MTimeNSec, 165 uid_t UID, gid_t GID, off_t Size) 166 : fs_st_atime(ATime), fs_st_mtime(MTime), 167 fs_st_atime_nsec(ATimeNSec), fs_st_mtime_nsec(MTimeNSec), 168 fs_st_uid(UID), fs_st_gid(GID), 169 fs_st_size(Size), Type(Type), Perms(Perms) {} 170 #elif defined(_WIN32) 171 basic_file_status(file_type Type, perms Perms, uint32_t LastAccessTimeHigh, 172 uint32_t LastAccessTimeLow, uint32_t LastWriteTimeHigh, 173 uint32_t LastWriteTimeLow, uint32_t FileSizeHigh, 174 uint32_t FileSizeLow) 175 : LastAccessedTimeHigh(LastAccessTimeHigh), 176 LastAccessedTimeLow(LastAccessTimeLow), 177 LastWriteTimeHigh(LastWriteTimeHigh), 178 LastWriteTimeLow(LastWriteTimeLow), FileSizeHigh(FileSizeHigh), 179 FileSizeLow(FileSizeLow), Type(Type), Perms(Perms) {} 180 #endif 181 182 // getters 183 file_type type() const { return Type; } 184 perms permissions() const { return Perms; } 185 186 /// The file access time as reported from the underlying file system. 187 /// 188 /// Also see comments on \c getLastModificationTime() related to the precision 189 /// of the returned value. 190 TimePoint<> getLastAccessedTime() const; 191 192 /// The file modification time as reported from the underlying file system. 193 /// 194 /// The returned value allows for nanosecond precision but the actual 195 /// resolution is an implementation detail of the underlying file system. 196 /// There is no guarantee for what kind of resolution you can expect, the 197 /// resolution can differ across platforms and even across mountpoints on the 198 /// same machine. 199 TimePoint<> getLastModificationTime() const; 200 201 #if defined(LLVM_ON_UNIX) 202 uint32_t getUser() const { return fs_st_uid; } 203 uint32_t getGroup() const { return fs_st_gid; } 204 uint64_t getSize() const { return fs_st_size; } 205 #elif defined (_WIN32) 206 uint32_t getUser() const { 207 return 9999; // Not applicable to Windows, so... 208 } 209 210 uint32_t getGroup() const { 211 return 9999; // Not applicable to Windows, so... 212 } 213 214 uint64_t getSize() const { 215 return (uint64_t(FileSizeHigh) << 32) + FileSizeLow; 216 } 217 #endif 218 219 // setters 220 void type(file_type v) { Type = v; } 221 void permissions(perms p) { Perms = p; } 222 }; 223 224 /// Represents the result of a call to sys::fs::status(). 225 class file_status : public basic_file_status { 226 friend bool equivalent(file_status A, file_status B); 227 228 #if defined(LLVM_ON_UNIX) 229 dev_t fs_st_dev = 0; 230 nlink_t fs_st_nlinks = 0; 231 ino_t fs_st_ino = 0; 232 #elif defined (_WIN32) 233 uint32_t NumLinks = 0; 234 uint32_t VolumeSerialNumber = 0; 235 uint64_t PathHash = 0; 236 #endif 237 238 public: 239 file_status() = default; 240 241 explicit file_status(file_type Type) : basic_file_status(Type) {} 242 243 #if defined(LLVM_ON_UNIX) 244 file_status(file_type Type, perms Perms, dev_t Dev, nlink_t Links, ino_t Ino, 245 time_t ATime, uint32_t ATimeNSec, 246 time_t MTime, uint32_t MTimeNSec, 247 uid_t UID, gid_t GID, off_t Size) 248 : basic_file_status(Type, Perms, ATime, ATimeNSec, MTime, MTimeNSec, 249 UID, GID, Size), 250 fs_st_dev(Dev), fs_st_nlinks(Links), fs_st_ino(Ino) {} 251 #elif defined(_WIN32) 252 file_status(file_type Type, perms Perms, uint32_t LinkCount, 253 uint32_t LastAccessTimeHigh, uint32_t LastAccessTimeLow, 254 uint32_t LastWriteTimeHigh, uint32_t LastWriteTimeLow, 255 uint32_t VolumeSerialNumber, uint32_t FileSizeHigh, 256 uint32_t FileSizeLow, uint64_t PathHash) 257 : basic_file_status(Type, Perms, LastAccessTimeHigh, LastAccessTimeLow, 258 LastWriteTimeHigh, LastWriteTimeLow, FileSizeHigh, 259 FileSizeLow), 260 NumLinks(LinkCount), VolumeSerialNumber(VolumeSerialNumber), 261 PathHash(PathHash) {} 262 #endif 263 264 UniqueID getUniqueID() const; 265 uint32_t getLinkCount() const; 266 }; 267 268 /// @} 269 /// @name Physical Operators 270 /// @{ 271 272 /// Make \a path an absolute path. 273 /// 274 /// Makes \a path absolute using the \a current_directory if it is not already. 275 /// An empty \a path will result in the \a current_directory. 276 /// 277 /// /absolute/path => /absolute/path 278 /// relative/../path => <current-directory>/relative/../path 279 /// 280 /// @param path A path that is modified to be an absolute path. 281 void make_absolute(const Twine ¤t_directory, SmallVectorImpl<char> &path); 282 283 /// Make \a path an absolute path. 284 /// 285 /// Makes \a path absolute using the current directory if it is not already. An 286 /// empty \a path will result in the current directory. 287 /// 288 /// /absolute/path => /absolute/path 289 /// relative/../path => <current-directory>/relative/../path 290 /// 291 /// @param path A path that is modified to be an absolute path. 292 /// @returns errc::success if \a path has been made absolute, otherwise a 293 /// platform-specific error_code. 294 std::error_code make_absolute(SmallVectorImpl<char> &path); 295 296 /// Create all the non-existent directories in path. 297 /// 298 /// @param path Directories to create. 299 /// @returns errc::success if is_directory(path), otherwise a platform 300 /// specific error_code. If IgnoreExisting is false, also returns 301 /// error if the directory already existed. 302 std::error_code create_directories(const Twine &path, 303 bool IgnoreExisting = true, 304 perms Perms = owner_all | group_all); 305 306 /// Create the directory in path. 307 /// 308 /// @param path Directory to create. 309 /// @returns errc::success if is_directory(path), otherwise a platform 310 /// specific error_code. If IgnoreExisting is false, also returns 311 /// error if the directory already existed. 312 std::error_code create_directory(const Twine &path, bool IgnoreExisting = true, 313 perms Perms = owner_all | group_all); 314 315 /// Create a link from \a from to \a to. 316 /// 317 /// The link may be a soft or a hard link, depending on the platform. The caller 318 /// may not assume which one. Currently on windows it creates a hard link since 319 /// soft links require extra privileges. On unix, it creates a soft link since 320 /// hard links don't work on SMB file systems. 321 /// 322 /// @param to The path to hard link to. 323 /// @param from The path to hard link from. This is created. 324 /// @returns errc::success if the link was created, otherwise a platform 325 /// specific error_code. 326 std::error_code create_link(const Twine &to, const Twine &from); 327 328 /// Create a hard link from \a from to \a to, or return an error. 329 /// 330 /// @param to The path to hard link to. 331 /// @param from The path to hard link from. This is created. 332 /// @returns errc::success if the link was created, otherwise a platform 333 /// specific error_code. 334 std::error_code create_hard_link(const Twine &to, const Twine &from); 335 336 /// Collapse all . and .. patterns, resolve all symlinks, and optionally 337 /// expand ~ expressions to the user's home directory. 338 /// 339 /// @param path The path to resolve. 340 /// @param output The location to store the resolved path. 341 /// @param expand_tilde If true, resolves ~ expressions to the user's home 342 /// directory. 343 std::error_code real_path(const Twine &path, SmallVectorImpl<char> &output, 344 bool expand_tilde = false); 345 346 /// Expands ~ expressions to the user's home directory. On Unix ~user 347 /// directories are resolved as well. 348 /// 349 /// @param path The path to resolve. 350 void expand_tilde(const Twine &path, SmallVectorImpl<char> &output); 351 352 /// Get the current path. 353 /// 354 /// @param result Holds the current path on return. 355 /// @returns errc::success if the current path has been stored in result, 356 /// otherwise a platform-specific error_code. 357 std::error_code current_path(SmallVectorImpl<char> &result); 358 359 /// Set the current path. 360 /// 361 /// @param path The path to set. 362 /// @returns errc::success if the current path was successfully set, 363 /// otherwise a platform-specific error_code. 364 std::error_code set_current_path(const Twine &path); 365 366 /// Remove path. Equivalent to POSIX remove(). 367 /// 368 /// @param path Input path. 369 /// @returns errc::success if path has been removed or didn't exist, otherwise a 370 /// platform-specific error code. If IgnoreNonExisting is false, also 371 /// returns error if the file didn't exist. 372 std::error_code remove(const Twine &path, bool IgnoreNonExisting = true); 373 374 /// Recursively delete a directory. 375 /// 376 /// @param path Input path. 377 /// @returns errc::success if path has been removed or didn't exist, otherwise a 378 /// platform-specific error code. 379 std::error_code remove_directories(const Twine &path, bool IgnoreErrors = true); 380 381 /// Rename \a from to \a to. 382 /// 383 /// Files are renamed as if by POSIX rename(), except that on Windows there may 384 /// be a short interval of time during which the destination file does not 385 /// exist. 386 /// 387 /// @param from The path to rename from. 388 /// @param to The path to rename to. This is created. 389 std::error_code rename(const Twine &from, const Twine &to); 390 391 /// Copy the contents of \a From to \a To. 392 /// 393 /// @param From The path to copy from. 394 /// @param To The path to copy to. This is created. 395 std::error_code copy_file(const Twine &From, const Twine &To); 396 397 /// Copy the contents of \a From to \a To. 398 /// 399 /// @param From The path to copy from. 400 /// @param ToFD The open file descriptor of the destination file. 401 std::error_code copy_file(const Twine &From, int ToFD); 402 403 /// Resize path to size. File is resized as if by POSIX truncate(). 404 /// 405 /// @param FD Input file descriptor. 406 /// @param Size Size to resize to. 407 /// @returns errc::success if \a path has been resized to \a size, otherwise a 408 /// platform-specific error_code. 409 std::error_code resize_file(int FD, uint64_t Size); 410 411 /// Resize \p FD to \p Size before mapping \a mapped_file_region::readwrite. On 412 /// non-Windows, this calls \a resize_file(). On Windows, this is a no-op, 413 /// since the subsequent mapping (via \c CreateFileMapping) automatically 414 /// extends the file. 415 inline std::error_code resize_file_before_mapping_readwrite(int FD, 416 uint64_t Size) { 417 #ifdef _WIN32 418 (void)FD; 419 (void)Size; 420 return std::error_code(); 421 #else 422 return resize_file(FD, Size); 423 #endif 424 } 425 426 /// Compute an MD5 hash of a file's contents. 427 /// 428 /// @param FD Input file descriptor. 429 /// @returns An MD5Result with the hash computed, if successful, otherwise a 430 /// std::error_code. 431 ErrorOr<MD5::MD5Result> md5_contents(int FD); 432 433 /// Version of compute_md5 that doesn't require an open file descriptor. 434 ErrorOr<MD5::MD5Result> md5_contents(const Twine &Path); 435 436 /// @} 437 /// @name Physical Observers 438 /// @{ 439 440 /// Does file exist? 441 /// 442 /// @param status A basic_file_status previously returned from stat. 443 /// @returns True if the file represented by status exists, false if it does 444 /// not. 445 bool exists(const basic_file_status &status); 446 447 enum class AccessMode { Exist, Write, Execute }; 448 449 /// Can the file be accessed? 450 /// 451 /// @param Path Input path. 452 /// @returns errc::success if the path can be accessed, otherwise a 453 /// platform-specific error_code. 454 std::error_code access(const Twine &Path, AccessMode Mode); 455 456 /// Does file exist? 457 /// 458 /// @param Path Input path. 459 /// @returns True if it exists, false otherwise. 460 inline bool exists(const Twine &Path) { 461 return !access(Path, AccessMode::Exist); 462 } 463 464 /// Can we execute this file? 465 /// 466 /// @param Path Input path. 467 /// @returns True if we can execute it, false otherwise. 468 bool can_execute(const Twine &Path); 469 470 /// Can we write this file? 471 /// 472 /// @param Path Input path. 473 /// @returns True if we can write to it, false otherwise. 474 inline bool can_write(const Twine &Path) { 475 return !access(Path, AccessMode::Write); 476 } 477 478 /// Do file_status's represent the same thing? 479 /// 480 /// @param A Input file_status. 481 /// @param B Input file_status. 482 /// 483 /// assert(status_known(A) || status_known(B)); 484 /// 485 /// @returns True if A and B both represent the same file system entity, false 486 /// otherwise. 487 bool equivalent(file_status A, file_status B); 488 489 /// Do paths represent the same thing? 490 /// 491 /// assert(status_known(A) || status_known(B)); 492 /// 493 /// @param A Input path A. 494 /// @param B Input path B. 495 /// @param result Set to true if stat(A) and stat(B) have the same device and 496 /// inode (or equivalent). 497 /// @returns errc::success if result has been successfully set, otherwise a 498 /// platform-specific error_code. 499 std::error_code equivalent(const Twine &A, const Twine &B, bool &result); 500 501 /// Simpler version of equivalent for clients that don't need to 502 /// differentiate between an error and false. 503 inline bool equivalent(const Twine &A, const Twine &B) { 504 bool result; 505 return !equivalent(A, B, result) && result; 506 } 507 508 /// Is the file mounted on a local filesystem? 509 /// 510 /// @param path Input path. 511 /// @param result Set to true if \a path is on fixed media such as a hard disk, 512 /// false if it is not. 513 /// @returns errc::success if result has been successfully set, otherwise a 514 /// platform specific error_code. 515 std::error_code is_local(const Twine &path, bool &result); 516 517 /// Version of is_local accepting an open file descriptor. 518 std::error_code is_local(int FD, bool &result); 519 520 /// Simpler version of is_local for clients that don't need to 521 /// differentiate between an error and false. 522 inline bool is_local(const Twine &Path) { 523 bool Result; 524 return !is_local(Path, Result) && Result; 525 } 526 527 /// Simpler version of is_local accepting an open file descriptor for 528 /// clients that don't need to differentiate between an error and false. 529 inline bool is_local(int FD) { 530 bool Result; 531 return !is_local(FD, Result) && Result; 532 } 533 534 /// Does status represent a directory? 535 /// 536 /// @param Path The path to get the type of. 537 /// @param Follow For symbolic links, indicates whether to return the file type 538 /// of the link itself, or of the target. 539 /// @returns A value from the file_type enumeration indicating the type of file. 540 file_type get_file_type(const Twine &Path, bool Follow = true); 541 542 /// Does status represent a directory? 543 /// 544 /// @param status A basic_file_status previously returned from status. 545 /// @returns status.type() == file_type::directory_file. 546 bool is_directory(const basic_file_status &status); 547 548 /// Is path a directory? 549 /// 550 /// @param path Input path. 551 /// @param result Set to true if \a path is a directory (after following 552 /// symlinks, false if it is not. Undefined otherwise. 553 /// @returns errc::success if result has been successfully set, otherwise a 554 /// platform-specific error_code. 555 std::error_code is_directory(const Twine &path, bool &result); 556 557 /// Simpler version of is_directory for clients that don't need to 558 /// differentiate between an error and false. 559 inline bool is_directory(const Twine &Path) { 560 bool Result; 561 return !is_directory(Path, Result) && Result; 562 } 563 564 /// Does status represent a regular file? 565 /// 566 /// @param status A basic_file_status previously returned from status. 567 /// @returns status_known(status) && status.type() == file_type::regular_file. 568 bool is_regular_file(const basic_file_status &status); 569 570 /// Is path a regular file? 571 /// 572 /// @param path Input path. 573 /// @param result Set to true if \a path is a regular file (after following 574 /// symlinks), false if it is not. Undefined otherwise. 575 /// @returns errc::success if result has been successfully set, otherwise a 576 /// platform-specific error_code. 577 std::error_code is_regular_file(const Twine &path, bool &result); 578 579 /// Simpler version of is_regular_file for clients that don't need to 580 /// differentiate between an error and false. 581 inline bool is_regular_file(const Twine &Path) { 582 bool Result; 583 if (is_regular_file(Path, Result)) 584 return false; 585 return Result; 586 } 587 588 /// Does status represent a symlink file? 589 /// 590 /// @param status A basic_file_status previously returned from status. 591 /// @returns status_known(status) && status.type() == file_type::symlink_file. 592 bool is_symlink_file(const basic_file_status &status); 593 594 /// Is path a symlink file? 595 /// 596 /// @param path Input path. 597 /// @param result Set to true if \a path is a symlink file, false if it is not. 598 /// Undefined otherwise. 599 /// @returns errc::success if result has been successfully set, otherwise a 600 /// platform-specific error_code. 601 std::error_code is_symlink_file(const Twine &path, bool &result); 602 603 /// Simpler version of is_symlink_file for clients that don't need to 604 /// differentiate between an error and false. 605 inline bool is_symlink_file(const Twine &Path) { 606 bool Result; 607 if (is_symlink_file(Path, Result)) 608 return false; 609 return Result; 610 } 611 612 /// Does this status represent something that exists but is not a 613 /// directory or regular file? 614 /// 615 /// @param status A basic_file_status previously returned from status. 616 /// @returns exists(s) && !is_regular_file(s) && !is_directory(s) 617 bool is_other(const basic_file_status &status); 618 619 /// Is path something that exists but is not a directory, 620 /// regular file, or symlink? 621 /// 622 /// @param path Input path. 623 /// @param result Set to true if \a path exists, but is not a directory, regular 624 /// file, or a symlink, false if it does not. Undefined otherwise. 625 /// @returns errc::success if result has been successfully set, otherwise a 626 /// platform-specific error_code. 627 std::error_code is_other(const Twine &path, bool &result); 628 629 /// Get file status as if by POSIX stat(). 630 /// 631 /// @param path Input path. 632 /// @param result Set to the file status. 633 /// @param follow When true, follows symlinks. Otherwise, the symlink itself is 634 /// statted. 635 /// @returns errc::success if result has been successfully set, otherwise a 636 /// platform-specific error_code. 637 std::error_code status(const Twine &path, file_status &result, 638 bool follow = true); 639 640 /// A version for when a file descriptor is already available. 641 std::error_code status(int FD, file_status &Result); 642 643 #ifdef _WIN32 644 /// A version for when a file descriptor is already available. 645 std::error_code status(file_t FD, file_status &Result); 646 #endif 647 648 /// Get file creation mode mask of the process. 649 /// 650 /// @returns Mask reported by umask(2) 651 /// @note There is no umask on Windows. This function returns 0 always 652 /// on Windows. This function does not return an error_code because 653 /// umask(2) never fails. It is not thread safe. 654 unsigned getUmask(); 655 656 /// Set file permissions. 657 /// 658 /// @param Path File to set permissions on. 659 /// @param Permissions New file permissions. 660 /// @returns errc::success if the permissions were successfully set, otherwise 661 /// a platform-specific error_code. 662 /// @note On Windows, all permissions except *_write are ignored. Using any of 663 /// owner_write, group_write, or all_write will make the file writable. 664 /// Otherwise, the file will be marked as read-only. 665 std::error_code setPermissions(const Twine &Path, perms Permissions); 666 667 /// Vesion of setPermissions accepting a file descriptor. 668 /// TODO Delete the path based overload once we implement the FD based overload 669 /// on Windows. 670 std::error_code setPermissions(int FD, perms Permissions); 671 672 /// Get file permissions. 673 /// 674 /// @param Path File to get permissions from. 675 /// @returns the permissions if they were successfully retrieved, otherwise a 676 /// platform-specific error_code. 677 /// @note On Windows, if the file does not have the FILE_ATTRIBUTE_READONLY 678 /// attribute, all_all will be returned. Otherwise, all_read | all_exe 679 /// will be returned. 680 ErrorOr<perms> getPermissions(const Twine &Path); 681 682 /// Get file size. 683 /// 684 /// @param Path Input path. 685 /// @param Result Set to the size of the file in \a Path. 686 /// @returns errc::success if result has been successfully set, otherwise a 687 /// platform-specific error_code. 688 inline std::error_code file_size(const Twine &Path, uint64_t &Result) { 689 file_status Status; 690 std::error_code EC = status(Path, Status); 691 if (EC) 692 return EC; 693 Result = Status.getSize(); 694 return std::error_code(); 695 } 696 697 /// Set the file modification and access time. 698 /// 699 /// @returns errc::success if the file times were successfully set, otherwise a 700 /// platform-specific error_code or errc::function_not_supported on 701 /// platforms where the functionality isn't available. 702 std::error_code setLastAccessAndModificationTime(int FD, TimePoint<> AccessTime, 703 TimePoint<> ModificationTime); 704 705 /// Simpler version that sets both file modification and access time to the same 706 /// time. 707 inline std::error_code setLastAccessAndModificationTime(int FD, 708 TimePoint<> Time) { 709 return setLastAccessAndModificationTime(FD, Time, Time); 710 } 711 712 /// Is status available? 713 /// 714 /// @param s Input file status. 715 /// @returns True if status() != status_error. 716 bool status_known(const basic_file_status &s); 717 718 /// Is status available? 719 /// 720 /// @param path Input path. 721 /// @param result Set to true if status() != status_error. 722 /// @returns errc::success if result has been successfully set, otherwise a 723 /// platform-specific error_code. 724 std::error_code status_known(const Twine &path, bool &result); 725 726 enum CreationDisposition : unsigned { 727 /// CD_CreateAlways - When opening a file: 728 /// * If it already exists, truncate it. 729 /// * If it does not already exist, create a new file. 730 CD_CreateAlways = 0, 731 732 /// CD_CreateNew - When opening a file: 733 /// * If it already exists, fail. 734 /// * If it does not already exist, create a new file. 735 CD_CreateNew = 1, 736 737 /// CD_OpenExisting - When opening a file: 738 /// * If it already exists, open the file with the offset set to 0. 739 /// * If it does not already exist, fail. 740 CD_OpenExisting = 2, 741 742 /// CD_OpenAlways - When opening a file: 743 /// * If it already exists, open the file with the offset set to 0. 744 /// * If it does not already exist, create a new file. 745 CD_OpenAlways = 3, 746 }; 747 748 enum FileAccess : unsigned { 749 FA_Read = 1, 750 FA_Write = 2, 751 }; 752 753 enum OpenFlags : unsigned { 754 OF_None = 0, 755 756 /// The file should be opened in text mode on platforms like z/OS that make 757 /// this distinction. 758 OF_Text = 1, 759 760 /// The file should use a carriage linefeed '\r\n'. This flag should only be 761 /// used with OF_Text. Only makes a difference on Windows. 762 OF_CRLF = 2, 763 764 /// The file should be opened in text mode and use a carriage linefeed '\r\n'. 765 /// This flag has the same functionality as OF_Text on z/OS but adds a 766 /// carriage linefeed on Windows. 767 OF_TextWithCRLF = OF_Text | OF_CRLF, 768 769 /// The file should be opened in append mode. 770 OF_Append = 4, 771 772 /// The returned handle can be used for deleting the file. Only makes a 773 /// difference on windows. 774 OF_Delete = 8, 775 776 /// When a child process is launched, this file should remain open in the 777 /// child process. 778 OF_ChildInherit = 16, 779 780 /// Force files Atime to be updated on access. Only makes a difference on 781 /// Windows. 782 OF_UpdateAtime = 32, 783 }; 784 785 /// Create a potentially unique file name but does not create it. 786 /// 787 /// Generates a unique path suitable for a temporary file but does not 788 /// open or create the file. The name is based on \a Model with '%' 789 /// replaced by a random char in [0-9a-f]. If \a MakeAbsolute is true 790 /// then the system's temp directory is prepended first. If \a MakeAbsolute 791 /// is false the current directory will be used instead. 792 /// 793 /// This function does not check if the file exists. If you want to be sure 794 /// that the file does not yet exist, you should use enough '%' characters 795 /// in your model to ensure this. Each '%' gives 4-bits of entropy so you can 796 /// use 32 of them to get 128 bits of entropy. 797 /// 798 /// Example: clang-%%-%%-%%-%%-%%.s => clang-a0-b1-c2-d3-e4.s 799 /// 800 /// @param Model Name to base unique path off of. 801 /// @param ResultPath Set to the file's path. 802 /// @param MakeAbsolute Whether to use the system temp directory. 803 void createUniquePath(const Twine &Model, SmallVectorImpl<char> &ResultPath, 804 bool MakeAbsolute); 805 806 /// Create a uniquely named file. 807 /// 808 /// Generates a unique path suitable for a temporary file and then opens it as a 809 /// file. The name is based on \a Model with '%' replaced by a random char in 810 /// [0-9a-f]. If \a Model is not an absolute path, the temporary file will be 811 /// created in the current directory. 812 /// 813 /// Example: clang-%%-%%-%%-%%-%%.s => clang-a0-b1-c2-d3-e4.s 814 /// 815 /// This is an atomic operation. Either the file is created and opened, or the 816 /// file system is left untouched. 817 /// 818 /// The intended use is for files that are to be kept, possibly after 819 /// renaming them. For example, when running 'clang -c foo.o', the file can 820 /// be first created as foo-abc123.o and then renamed. 821 /// 822 /// @param Model Name to base unique path off of. 823 /// @param ResultFD Set to the opened file's file descriptor. 824 /// @param ResultPath Set to the opened file's absolute path. 825 /// @param Flags Set to the opened file's flags. 826 /// @param Mode Set to the opened file's permissions. 827 /// @returns errc::success if Result{FD,Path} have been successfully set, 828 /// otherwise a platform-specific error_code. 829 std::error_code createUniqueFile(const Twine &Model, int &ResultFD, 830 SmallVectorImpl<char> &ResultPath, 831 OpenFlags Flags = OF_None, 832 unsigned Mode = all_read | all_write); 833 834 /// Simpler version for clients that don't want an open file. An empty 835 /// file will still be created. 836 std::error_code createUniqueFile(const Twine &Model, 837 SmallVectorImpl<char> &ResultPath, 838 unsigned Mode = all_read | all_write); 839 840 /// Represents a temporary file. 841 /// 842 /// The temporary file must be eventually discarded or given a final name and 843 /// kept. 844 /// 845 /// The destructor doesn't implicitly discard because there is no way to 846 /// properly handle errors in a destructor. 847 class TempFile { 848 bool Done = false; 849 TempFile(StringRef Name, int FD); 850 851 public: 852 /// This creates a temporary file with createUniqueFile and schedules it for 853 /// deletion with sys::RemoveFileOnSignal. 854 static Expected<TempFile> create(const Twine &Model, 855 unsigned Mode = all_read | all_write, 856 OpenFlags ExtraFlags = OF_None); 857 TempFile(TempFile &&Other); 858 TempFile &operator=(TempFile &&Other); 859 860 // Name of the temporary file. 861 std::string TmpName; 862 863 // The open file descriptor. 864 int FD = -1; 865 866 #ifdef _WIN32 867 // Whether we need to manually remove the file on close. 868 bool RemoveOnClose = false; 869 #endif 870 871 // Keep this with the given name. 872 Error keep(const Twine &Name); 873 874 // Keep this with the temporary name. 875 Error keep(); 876 877 // Delete the file. 878 Error discard(); 879 880 // This checks that keep or delete was called. 881 ~TempFile(); 882 }; 883 884 /// Create a file in the system temporary directory. 885 /// 886 /// The filename is of the form prefix-random_chars.suffix. Since the directory 887 /// is not know to the caller, Prefix and Suffix cannot have path separators. 888 /// The files are created with mode 0600. 889 /// 890 /// This should be used for things like a temporary .s that is removed after 891 /// running the assembler. 892 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, 893 int &ResultFD, 894 SmallVectorImpl<char> &ResultPath, 895 OpenFlags Flags = OF_None); 896 897 /// Simpler version for clients that don't want an open file. An empty 898 /// file will still be created. 899 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, 900 SmallVectorImpl<char> &ResultPath, 901 OpenFlags Flags = OF_None); 902 903 std::error_code createUniqueDirectory(const Twine &Prefix, 904 SmallVectorImpl<char> &ResultPath); 905 906 /// Get a unique name, not currently exisiting in the filesystem. Subject 907 /// to race conditions, prefer to use createUniqueFile instead. 908 /// 909 /// Similar to createUniqueFile, but instead of creating a file only 910 /// checks if it exists. This function is subject to race conditions, if you 911 /// want to use the returned name to actually create a file, use 912 /// createUniqueFile instead. 913 std::error_code getPotentiallyUniqueFileName(const Twine &Model, 914 SmallVectorImpl<char> &ResultPath); 915 916 /// Get a unique temporary file name, not currently exisiting in the 917 /// filesystem. Subject to race conditions, prefer to use createTemporaryFile 918 /// instead. 919 /// 920 /// Similar to createTemporaryFile, but instead of creating a file only 921 /// checks if it exists. This function is subject to race conditions, if you 922 /// want to use the returned name to actually create a file, use 923 /// createTemporaryFile instead. 924 std::error_code 925 getPotentiallyUniqueTempFileName(const Twine &Prefix, StringRef Suffix, 926 SmallVectorImpl<char> &ResultPath); 927 928 inline OpenFlags operator|(OpenFlags A, OpenFlags B) { 929 return OpenFlags(unsigned(A) | unsigned(B)); 930 } 931 932 inline OpenFlags &operator|=(OpenFlags &A, OpenFlags B) { 933 A = A | B; 934 return A; 935 } 936 937 inline FileAccess operator|(FileAccess A, FileAccess B) { 938 return FileAccess(unsigned(A) | unsigned(B)); 939 } 940 941 inline FileAccess &operator|=(FileAccess &A, FileAccess B) { 942 A = A | B; 943 return A; 944 } 945 946 /// @brief Opens a file with the specified creation disposition, access mode, 947 /// and flags and returns a file descriptor. 948 /// 949 /// The caller is responsible for closing the file descriptor once they are 950 /// finished with it. 951 /// 952 /// @param Name The path of the file to open, relative or absolute. 953 /// @param ResultFD If the file could be opened successfully, its descriptor 954 /// is stored in this location. Otherwise, this is set to -1. 955 /// @param Disp Value specifying the existing-file behavior. 956 /// @param Access Value specifying whether to open the file in read, write, or 957 /// read-write mode. 958 /// @param Flags Additional flags. 959 /// @param Mode The access permissions of the file, represented in octal. 960 /// @returns errc::success if \a Name has been opened, otherwise a 961 /// platform-specific error_code. 962 std::error_code openFile(const Twine &Name, int &ResultFD, 963 CreationDisposition Disp, FileAccess Access, 964 OpenFlags Flags, unsigned Mode = 0666); 965 966 /// @brief Opens a file with the specified creation disposition, access mode, 967 /// and flags and returns a platform-specific file object. 968 /// 969 /// The caller is responsible for closing the file object once they are 970 /// finished with it. 971 /// 972 /// @param Name The path of the file to open, relative or absolute. 973 /// @param Disp Value specifying the existing-file behavior. 974 /// @param Access Value specifying whether to open the file in read, write, or 975 /// read-write mode. 976 /// @param Flags Additional flags. 977 /// @param Mode The access permissions of the file, represented in octal. 978 /// @returns errc::success if \a Name has been opened, otherwise a 979 /// platform-specific error_code. 980 Expected<file_t> openNativeFile(const Twine &Name, CreationDisposition Disp, 981 FileAccess Access, OpenFlags Flags, 982 unsigned Mode = 0666); 983 984 /// Converts from a Posix file descriptor number to a native file handle. 985 /// On Windows, this retreives the underlying handle. On non-Windows, this is a 986 /// no-op. 987 file_t convertFDToNativeFile(int FD); 988 989 #ifndef _WIN32 990 inline file_t convertFDToNativeFile(int FD) { return FD; } 991 #endif 992 993 /// Return an open handle to standard in. On Unix, this is typically FD 0. 994 /// Returns kInvalidFile when the stream is closed. 995 file_t getStdinHandle(); 996 997 /// Return an open handle to standard out. On Unix, this is typically FD 1. 998 /// Returns kInvalidFile when the stream is closed. 999 file_t getStdoutHandle(); 1000 1001 /// Return an open handle to standard error. On Unix, this is typically FD 2. 1002 /// Returns kInvalidFile when the stream is closed. 1003 file_t getStderrHandle(); 1004 1005 /// Reads \p Buf.size() bytes from \p FileHandle into \p Buf. Returns the number 1006 /// of bytes actually read. On Unix, this is equivalent to `return ::read(FD, 1007 /// Buf.data(), Buf.size())`, with error reporting. Returns 0 when reaching EOF. 1008 /// 1009 /// @param FileHandle File to read from. 1010 /// @param Buf Buffer to read into. 1011 /// @returns The number of bytes read, or error. 1012 Expected<size_t> readNativeFile(file_t FileHandle, MutableArrayRef<char> Buf); 1013 1014 /// Default chunk size for \a readNativeFileToEOF(). 1015 enum : size_t { DefaultReadChunkSize = 4 * 4096 }; 1016 1017 /// Reads from \p FileHandle until EOF, appending to \p Buffer in chunks of 1018 /// size \p ChunkSize. 1019 /// 1020 /// This calls \a readNativeFile() in a loop. On Error, previous chunks that 1021 /// were read successfully are left in \p Buffer and returned. 1022 /// 1023 /// Note: For reading the final chunk at EOF, \p Buffer's capacity needs extra 1024 /// storage of \p ChunkSize. 1025 /// 1026 /// \param FileHandle File to read from. 1027 /// \param Buffer Where to put the file content. 1028 /// \param ChunkSize Size of chunks. 1029 /// \returns The error if EOF was not found. 1030 Error readNativeFileToEOF(file_t FileHandle, SmallVectorImpl<char> &Buffer, 1031 ssize_t ChunkSize = DefaultReadChunkSize); 1032 1033 /// Reads \p Buf.size() bytes from \p FileHandle at offset \p Offset into \p 1034 /// Buf. If 'pread' is available, this will use that, otherwise it will use 1035 /// 'lseek'. Returns the number of bytes actually read. Returns 0 when reaching 1036 /// EOF. 1037 /// 1038 /// @param FileHandle File to read from. 1039 /// @param Buf Buffer to read into. 1040 /// @param Offset Offset into the file at which the read should occur. 1041 /// @returns The number of bytes read, or error. 1042 Expected<size_t> readNativeFileSlice(file_t FileHandle, 1043 MutableArrayRef<char> Buf, 1044 uint64_t Offset); 1045 1046 /// @brief Opens the file with the given name in a write-only or read-write 1047 /// mode, returning its open file descriptor. If the file does not exist, it 1048 /// is created. 1049 /// 1050 /// The caller is responsible for closing the file descriptor once they are 1051 /// finished with it. 1052 /// 1053 /// @param Name The path of the file to open, relative or absolute. 1054 /// @param ResultFD If the file could be opened successfully, its descriptor 1055 /// is stored in this location. Otherwise, this is set to -1. 1056 /// @param Flags Additional flags used to determine whether the file should be 1057 /// opened in, for example, read-write or in write-only mode. 1058 /// @param Mode The access permissions of the file, represented in octal. 1059 /// @returns errc::success if \a Name has been opened, otherwise a 1060 /// platform-specific error_code. 1061 inline std::error_code 1062 openFileForWrite(const Twine &Name, int &ResultFD, 1063 CreationDisposition Disp = CD_CreateAlways, 1064 OpenFlags Flags = OF_None, unsigned Mode = 0666) { 1065 return openFile(Name, ResultFD, Disp, FA_Write, Flags, Mode); 1066 } 1067 1068 /// @brief Opens the file with the given name in a write-only or read-write 1069 /// mode, returning its open file descriptor. If the file does not exist, it 1070 /// is created. 1071 /// 1072 /// The caller is responsible for closing the freeing the file once they are 1073 /// finished with it. 1074 /// 1075 /// @param Name The path of the file to open, relative or absolute. 1076 /// @param Flags Additional flags used to determine whether the file should be 1077 /// opened in, for example, read-write or in write-only mode. 1078 /// @param Mode The access permissions of the file, represented in octal. 1079 /// @returns a platform-specific file descriptor if \a Name has been opened, 1080 /// otherwise an error object. 1081 inline Expected<file_t> openNativeFileForWrite(const Twine &Name, 1082 CreationDisposition Disp, 1083 OpenFlags Flags, 1084 unsigned Mode = 0666) { 1085 return openNativeFile(Name, Disp, FA_Write, Flags, Mode); 1086 } 1087 1088 /// @brief Opens the file with the given name in a write-only or read-write 1089 /// mode, returning its open file descriptor. If the file does not exist, it 1090 /// is created. 1091 /// 1092 /// The caller is responsible for closing the file descriptor once they are 1093 /// finished with it. 1094 /// 1095 /// @param Name The path of the file to open, relative or absolute. 1096 /// @param ResultFD If the file could be opened successfully, its descriptor 1097 /// is stored in this location. Otherwise, this is set to -1. 1098 /// @param Flags Additional flags used to determine whether the file should be 1099 /// opened in, for example, read-write or in write-only mode. 1100 /// @param Mode The access permissions of the file, represented in octal. 1101 /// @returns errc::success if \a Name has been opened, otherwise a 1102 /// platform-specific error_code. 1103 inline std::error_code openFileForReadWrite(const Twine &Name, int &ResultFD, 1104 CreationDisposition Disp, 1105 OpenFlags Flags, 1106 unsigned Mode = 0666) { 1107 return openFile(Name, ResultFD, Disp, FA_Write | FA_Read, Flags, Mode); 1108 } 1109 1110 /// @brief Opens the file with the given name in a write-only or read-write 1111 /// mode, returning its open file descriptor. If the file does not exist, it 1112 /// is created. 1113 /// 1114 /// The caller is responsible for closing the freeing the file once they are 1115 /// finished with it. 1116 /// 1117 /// @param Name The path of the file to open, relative or absolute. 1118 /// @param Flags Additional flags used to determine whether the file should be 1119 /// opened in, for example, read-write or in write-only mode. 1120 /// @param Mode The access permissions of the file, represented in octal. 1121 /// @returns a platform-specific file descriptor if \a Name has been opened, 1122 /// otherwise an error object. 1123 inline Expected<file_t> openNativeFileForReadWrite(const Twine &Name, 1124 CreationDisposition Disp, 1125 OpenFlags Flags, 1126 unsigned Mode = 0666) { 1127 return openNativeFile(Name, Disp, FA_Write | FA_Read, Flags, Mode); 1128 } 1129 1130 /// @brief Opens the file with the given name in a read-only mode, returning 1131 /// its open file descriptor. 1132 /// 1133 /// The caller is responsible for closing the file descriptor once they are 1134 /// finished with it. 1135 /// 1136 /// @param Name The path of the file to open, relative or absolute. 1137 /// @param ResultFD If the file could be opened successfully, its descriptor 1138 /// is stored in this location. Otherwise, this is set to -1. 1139 /// @param RealPath If nonnull, extra work is done to determine the real path 1140 /// of the opened file, and that path is stored in this 1141 /// location. 1142 /// @returns errc::success if \a Name has been opened, otherwise a 1143 /// platform-specific error_code. 1144 std::error_code openFileForRead(const Twine &Name, int &ResultFD, 1145 OpenFlags Flags = OF_None, 1146 SmallVectorImpl<char> *RealPath = nullptr); 1147 1148 /// @brief Opens the file with the given name in a read-only mode, returning 1149 /// its open file descriptor. 1150 /// 1151 /// The caller is responsible for closing the freeing the file once they are 1152 /// finished with it. 1153 /// 1154 /// @param Name The path of the file to open, relative or absolute. 1155 /// @param RealPath If nonnull, extra work is done to determine the real path 1156 /// of the opened file, and that path is stored in this 1157 /// location. 1158 /// @returns a platform-specific file descriptor if \a Name has been opened, 1159 /// otherwise an error object. 1160 Expected<file_t> 1161 openNativeFileForRead(const Twine &Name, OpenFlags Flags = OF_None, 1162 SmallVectorImpl<char> *RealPath = nullptr); 1163 1164 /// Try to locks the file during the specified time. 1165 /// 1166 /// This function implements advisory locking on entire file. If it returns 1167 /// <em>errc::success</em>, the file is locked by the calling process. Until the 1168 /// process unlocks the file by calling \a unlockFile, all attempts to lock the 1169 /// same file will fail/block. The process that locked the file may assume that 1170 /// none of other processes read or write this file, provided that all processes 1171 /// lock the file prior to accessing its content. 1172 /// 1173 /// @param FD The descriptor representing the file to lock. 1174 /// @param Timeout Time in milliseconds that the process should wait before 1175 /// reporting lock failure. Zero value means try to get lock only 1176 /// once. 1177 /// @returns errc::success if lock is successfully obtained, 1178 /// errc::no_lock_available if the file cannot be locked, or platform-specific 1179 /// error_code otherwise. 1180 /// 1181 /// @note Care should be taken when using this function in a multithreaded 1182 /// context, as it may not prevent other threads in the same process from 1183 /// obtaining a lock on the same file, even if they are using a different file 1184 /// descriptor. 1185 std::error_code 1186 tryLockFile(int FD, 1187 std::chrono::milliseconds Timeout = std::chrono::milliseconds(0)); 1188 1189 /// Lock the file. 1190 /// 1191 /// This function acts as @ref tryLockFile but it waits infinitely. 1192 std::error_code lockFile(int FD); 1193 1194 /// Unlock the file. 1195 /// 1196 /// @param FD The descriptor representing the file to unlock. 1197 /// @returns errc::success if lock is successfully released or platform-specific 1198 /// error_code otherwise. 1199 std::error_code unlockFile(int FD); 1200 1201 /// @brief Close the file object. This should be used instead of ::close for 1202 /// portability. On error, the caller should assume the file is closed, as is 1203 /// the case for Process::SafelyCloseFileDescriptor 1204 /// 1205 /// @param F On input, this is the file to close. On output, the file is 1206 /// set to kInvalidFile. 1207 /// 1208 /// @returns An error code if closing the file failed. Typically, an error here 1209 /// means that the filesystem may have failed to perform some buffered writes. 1210 std::error_code closeFile(file_t &F); 1211 1212 #ifdef LLVM_ON_UNIX 1213 /// @brief Change ownership of a file. 1214 /// 1215 /// @param Owner The owner of the file to change to. 1216 /// @param Group The group of the file to change to. 1217 /// @returns errc::success if successfully updated file ownership, otherwise an 1218 /// error code is returned. 1219 std::error_code changeFileOwnership(int FD, uint32_t Owner, uint32_t Group); 1220 #endif 1221 1222 /// RAII class that facilitates file locking. 1223 class FileLocker { 1224 int FD; ///< Locked file handle. 1225 FileLocker(int FD) : FD(FD) {} 1226 friend class llvm::raw_fd_ostream; 1227 1228 public: 1229 FileLocker(const FileLocker &L) = delete; 1230 FileLocker(FileLocker &&L) : FD(L.FD) { L.FD = -1; } 1231 ~FileLocker() { 1232 if (FD != -1) 1233 unlockFile(FD); 1234 } 1235 FileLocker &operator=(FileLocker &&L) { 1236 FD = L.FD; 1237 L.FD = -1; 1238 return *this; 1239 } 1240 FileLocker &operator=(const FileLocker &L) = delete; 1241 std::error_code unlock() { 1242 if (FD != -1) { 1243 std::error_code Result = unlockFile(FD); 1244 FD = -1; 1245 return Result; 1246 } 1247 return std::error_code(); 1248 } 1249 }; 1250 1251 std::error_code getUniqueID(const Twine Path, UniqueID &Result); 1252 1253 /// Get disk space usage information. 1254 /// 1255 /// Note: Users must be careful about "Time Of Check, Time Of Use" kind of bug. 1256 /// Note: Windows reports results according to the quota allocated to the user. 1257 /// 1258 /// @param Path Input path. 1259 /// @returns a space_info structure filled with the capacity, free, and 1260 /// available space on the device \a Path is on. A platform specific error_code 1261 /// is returned on error. 1262 ErrorOr<space_info> disk_space(const Twine &Path); 1263 1264 /// This class represents a memory mapped file. It is based on 1265 /// boost::iostreams::mapped_file. 1266 class mapped_file_region { 1267 public: 1268 enum mapmode { 1269 readonly, ///< May only access map via const_data as read only. 1270 readwrite, ///< May access map via data and modify it. Written to path. 1271 priv ///< May modify via data, but changes are lost on destruction. 1272 }; 1273 1274 private: 1275 /// Platform-specific mapping state. 1276 size_t Size = 0; 1277 void *Mapping = nullptr; 1278 #ifdef _WIN32 1279 sys::fs::file_t FileHandle = nullptr; 1280 #endif 1281 mapmode Mode = readonly; 1282 1283 void copyFrom(const mapped_file_region &Copied) { 1284 Size = Copied.Size; 1285 Mapping = Copied.Mapping; 1286 #ifdef _WIN32 1287 FileHandle = Copied.FileHandle; 1288 #endif 1289 Mode = Copied.Mode; 1290 } 1291 1292 void moveFromImpl(mapped_file_region &Moved) { 1293 copyFrom(Moved); 1294 Moved.copyFrom(mapped_file_region()); 1295 } 1296 1297 void unmapImpl(); 1298 void dontNeedImpl(); 1299 1300 std::error_code init(sys::fs::file_t FD, uint64_t Offset, mapmode Mode); 1301 1302 public: 1303 mapped_file_region() = default; 1304 mapped_file_region(mapped_file_region &&Moved) { moveFromImpl(Moved); } 1305 mapped_file_region &operator=(mapped_file_region &&Moved) { 1306 unmap(); 1307 moveFromImpl(Moved); 1308 return *this; 1309 } 1310 1311 mapped_file_region(const mapped_file_region &) = delete; 1312 mapped_file_region &operator=(const mapped_file_region &) = delete; 1313 1314 /// \param fd An open file descriptor to map. Does not take ownership of fd. 1315 mapped_file_region(sys::fs::file_t fd, mapmode mode, size_t length, uint64_t offset, 1316 std::error_code &ec); 1317 1318 ~mapped_file_region() { unmapImpl(); } 1319 1320 /// Check if this is a valid mapping. 1321 explicit operator bool() const { return Mapping; } 1322 1323 /// Unmap. 1324 void unmap() { 1325 unmapImpl(); 1326 copyFrom(mapped_file_region()); 1327 } 1328 void dontNeed() { dontNeedImpl(); } 1329 1330 size_t size() const; 1331 char *data() const; 1332 1333 /// Get a const view of the data. Modifying this memory has undefined 1334 /// behavior. 1335 const char *const_data() const; 1336 1337 /// \returns The minimum alignment offset must be. 1338 static int alignment(); 1339 }; 1340 1341 /// Return the path to the main executable, given the value of argv[0] from 1342 /// program startup and the address of main itself. In extremis, this function 1343 /// may fail and return an empty path. 1344 std::string getMainExecutable(const char *argv0, void *MainExecAddr); 1345 1346 /// @} 1347 /// @name Iterators 1348 /// @{ 1349 1350 /// directory_entry - A single entry in a directory. 1351 class directory_entry { 1352 // FIXME: different platforms make different information available "for free" 1353 // when traversing a directory. The design of this class wraps most of the 1354 // information in basic_file_status, so on platforms where we can't populate 1355 // that whole structure, callers end up paying for a stat(). 1356 // std::filesystem::directory_entry may be a better model. 1357 std::string Path; 1358 file_type Type = file_type::type_unknown; // Most platforms can provide this. 1359 bool FollowSymlinks = true; // Affects the behavior of status(). 1360 basic_file_status Status; // If available. 1361 1362 public: 1363 explicit directory_entry(const Twine &Path, bool FollowSymlinks = true, 1364 file_type Type = file_type::type_unknown, 1365 basic_file_status Status = basic_file_status()) 1366 : Path(Path.str()), Type(Type), FollowSymlinks(FollowSymlinks), 1367 Status(Status) {} 1368 1369 directory_entry() = default; 1370 1371 void replace_filename(const Twine &Filename, file_type Type, 1372 basic_file_status Status = basic_file_status()); 1373 1374 const std::string &path() const { return Path; } 1375 // Get basic information about entry file (a subset of fs::status()). 1376 // On most platforms this is a stat() call. 1377 // On windows the information was already retrieved from the directory. 1378 ErrorOr<basic_file_status> status() const; 1379 // Get the type of this file. 1380 // On most platforms (Linux/Mac/Windows/BSD), this was already retrieved. 1381 // On some platforms (e.g. Solaris) this is a stat() call. 1382 file_type type() const { 1383 if (Type != file_type::type_unknown) 1384 return Type; 1385 auto S = status(); 1386 return S ? S->type() : file_type::type_unknown; 1387 } 1388 1389 bool operator==(const directory_entry& RHS) const { return Path == RHS.Path; } 1390 bool operator!=(const directory_entry& RHS) const { return !(*this == RHS); } 1391 bool operator< (const directory_entry& RHS) const; 1392 bool operator<=(const directory_entry& RHS) const; 1393 bool operator> (const directory_entry& RHS) const; 1394 bool operator>=(const directory_entry& RHS) const; 1395 }; 1396 1397 namespace detail { 1398 1399 struct DirIterState; 1400 1401 std::error_code directory_iterator_construct(DirIterState &, StringRef, bool); 1402 std::error_code directory_iterator_increment(DirIterState &); 1403 std::error_code directory_iterator_destruct(DirIterState &); 1404 1405 /// Keeps state for the directory_iterator. 1406 struct DirIterState { 1407 ~DirIterState() { 1408 directory_iterator_destruct(*this); 1409 } 1410 1411 intptr_t IterationHandle = 0; 1412 directory_entry CurrentEntry; 1413 }; 1414 1415 } // end namespace detail 1416 1417 /// directory_iterator - Iterates through the entries in path. There is no 1418 /// operator++ because we need an error_code. If it's really needed we can make 1419 /// it call report_fatal_error on error. 1420 class directory_iterator { 1421 std::shared_ptr<detail::DirIterState> State; 1422 bool FollowSymlinks = true; 1423 1424 public: 1425 explicit directory_iterator(const Twine &path, std::error_code &ec, 1426 bool follow_symlinks = true) 1427 : FollowSymlinks(follow_symlinks) { 1428 State = std::make_shared<detail::DirIterState>(); 1429 SmallString<128> path_storage; 1430 ec = detail::directory_iterator_construct( 1431 *State, path.toStringRef(path_storage), FollowSymlinks); 1432 } 1433 1434 explicit directory_iterator(const directory_entry &de, std::error_code &ec, 1435 bool follow_symlinks = true) 1436 : FollowSymlinks(follow_symlinks) { 1437 State = std::make_shared<detail::DirIterState>(); 1438 ec = detail::directory_iterator_construct( 1439 *State, de.path(), FollowSymlinks); 1440 } 1441 1442 /// Construct end iterator. 1443 directory_iterator() = default; 1444 1445 // No operator++ because we need error_code. 1446 directory_iterator &increment(std::error_code &ec) { 1447 ec = directory_iterator_increment(*State); 1448 return *this; 1449 } 1450 1451 const directory_entry &operator*() const { return State->CurrentEntry; } 1452 const directory_entry *operator->() const { return &State->CurrentEntry; } 1453 1454 bool operator==(const directory_iterator &RHS) const { 1455 if (State == RHS.State) 1456 return true; 1457 if (!RHS.State) 1458 return State->CurrentEntry == directory_entry(); 1459 if (!State) 1460 return RHS.State->CurrentEntry == directory_entry(); 1461 return State->CurrentEntry == RHS.State->CurrentEntry; 1462 } 1463 1464 bool operator!=(const directory_iterator &RHS) const { 1465 return !(*this == RHS); 1466 } 1467 }; 1468 1469 namespace detail { 1470 1471 /// Keeps state for the recursive_directory_iterator. 1472 struct RecDirIterState { 1473 std::vector<directory_iterator> Stack; 1474 uint16_t Level = 0; 1475 bool HasNoPushRequest = false; 1476 }; 1477 1478 } // end namespace detail 1479 1480 /// recursive_directory_iterator - Same as directory_iterator except for it 1481 /// recurses down into child directories. 1482 class recursive_directory_iterator { 1483 std::shared_ptr<detail::RecDirIterState> State; 1484 bool Follow; 1485 1486 public: 1487 recursive_directory_iterator() = default; 1488 explicit recursive_directory_iterator(const Twine &path, std::error_code &ec, 1489 bool follow_symlinks = true) 1490 : State(std::make_shared<detail::RecDirIterState>()), 1491 Follow(follow_symlinks) { 1492 State->Stack.push_back(directory_iterator(path, ec, Follow)); 1493 if (State->Stack.back() == directory_iterator()) 1494 State.reset(); 1495 } 1496 1497 // No operator++ because we need error_code. 1498 recursive_directory_iterator &increment(std::error_code &ec) { 1499 const directory_iterator end_itr = {}; 1500 1501 if (State->HasNoPushRequest) 1502 State->HasNoPushRequest = false; 1503 else { 1504 file_type type = State->Stack.back()->type(); 1505 if (type == file_type::symlink_file && Follow) { 1506 // Resolve the symlink: is it a directory to recurse into? 1507 ErrorOr<basic_file_status> status = State->Stack.back()->status(); 1508 if (status) 1509 type = status->type(); 1510 // Otherwise broken symlink, and we'll continue. 1511 } 1512 if (type == file_type::directory_file) { 1513 State->Stack.push_back( 1514 directory_iterator(*State->Stack.back(), ec, Follow)); 1515 if (State->Stack.back() != end_itr) { 1516 ++State->Level; 1517 return *this; 1518 } 1519 State->Stack.pop_back(); 1520 } 1521 } 1522 1523 while (!State->Stack.empty() 1524 && State->Stack.back().increment(ec) == end_itr) { 1525 State->Stack.pop_back(); 1526 --State->Level; 1527 } 1528 1529 // Check if we are done. If so, create an end iterator. 1530 if (State->Stack.empty()) 1531 State.reset(); 1532 1533 return *this; 1534 } 1535 1536 const directory_entry &operator*() const { return *State->Stack.back(); } 1537 const directory_entry *operator->() const { return &*State->Stack.back(); } 1538 1539 // observers 1540 /// Gets the current level. Starting path is at level 0. 1541 int level() const { return State->Level; } 1542 1543 /// Returns true if no_push has been called for this directory_entry. 1544 bool no_push_request() const { return State->HasNoPushRequest; } 1545 1546 // modifiers 1547 /// Goes up one level if Level > 0. 1548 void pop() { 1549 assert(State && "Cannot pop an end iterator!"); 1550 assert(State->Level > 0 && "Cannot pop an iterator with level < 1"); 1551 1552 const directory_iterator end_itr = {}; 1553 std::error_code ec; 1554 do { 1555 if (ec) 1556 report_fatal_error("Error incrementing directory iterator."); 1557 State->Stack.pop_back(); 1558 --State->Level; 1559 } while (!State->Stack.empty() 1560 && State->Stack.back().increment(ec) == end_itr); 1561 1562 // Check if we are done. If so, create an end iterator. 1563 if (State->Stack.empty()) 1564 State.reset(); 1565 } 1566 1567 /// Does not go down into the current directory_entry. 1568 void no_push() { State->HasNoPushRequest = true; } 1569 1570 bool operator==(const recursive_directory_iterator &RHS) const { 1571 return State == RHS.State; 1572 } 1573 1574 bool operator!=(const recursive_directory_iterator &RHS) const { 1575 return !(*this == RHS); 1576 } 1577 }; 1578 1579 /// @} 1580 1581 } // end namespace fs 1582 } // end namespace sys 1583 } // end namespace llvm 1584 1585 #endif // LLVM_SUPPORT_FILESYSTEM_H 1586