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