1//===- llvm/Support/Unix/Path.inc - Unix Path Implementation ----*- 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 implements the Unix specific implementation of the Path API. 10// 11//===----------------------------------------------------------------------===// 12 13//===----------------------------------------------------------------------===// 14//=== WARNING: Implementation here must contain only generic UNIX code that 15//=== is guaranteed to work on *all* UNIX variants. 16//===----------------------------------------------------------------------===// 17 18#include "Unix.h" 19#include <limits.h> 20#include <stdio.h> 21#if HAVE_SYS_STAT_H 22#include <sys/stat.h> 23#endif 24#if HAVE_FCNTL_H 25#include <fcntl.h> 26#endif 27#ifdef HAVE_UNISTD_H 28#include <unistd.h> 29#endif 30#ifdef HAVE_SYS_MMAN_H 31#include <sys/mman.h> 32#endif 33 34#include <dirent.h> 35#include <pwd.h> 36 37#ifdef __APPLE__ 38#include <mach-o/dyld.h> 39#include <sys/attr.h> 40#include <copyfile.h> 41#elif defined(__FreeBSD__) 42#include <osreldate.h> 43#if __FreeBSD_version >= 1300057 44#include <sys/auxv.h> 45#else 46#include <machine/elf.h> 47extern char **environ; 48#endif 49#elif defined(__DragonFly__) 50#include <sys/mount.h> 51#endif 52 53// Both stdio.h and cstdio are included via different paths and 54// stdcxx's cstdio doesn't include stdio.h, so it doesn't #undef the macros 55// either. 56#undef ferror 57#undef feof 58 59// For GNU Hurd 60#if defined(__GNU__) && !defined(PATH_MAX) 61# define PATH_MAX 4096 62# define MAXPATHLEN 4096 63#endif 64 65#include <sys/types.h> 66#if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && \ 67 !defined(__linux__) && !defined(__FreeBSD_kernel__) && !defined(_AIX) 68#include <sys/statvfs.h> 69#define STATVFS statvfs 70#define FSTATVFS fstatvfs 71#define STATVFS_F_FRSIZE(vfs) vfs.f_frsize 72#else 73#if defined(__OpenBSD__) || defined(__FreeBSD__) 74#include <sys/mount.h> 75#include <sys/param.h> 76#elif defined(__linux__) 77#if defined(HAVE_LINUX_MAGIC_H) 78#include <linux/magic.h> 79#else 80#if defined(HAVE_LINUX_NFS_FS_H) 81#include <linux/nfs_fs.h> 82#endif 83#if defined(HAVE_LINUX_SMB_H) 84#include <linux/smb.h> 85#endif 86#endif 87#include <sys/vfs.h> 88#elif defined(_AIX) 89#include <sys/statfs.h> 90 91// <sys/vmount.h> depends on `uint` to be a typedef from <sys/types.h> to 92// `uint_t`; however, <sys/types.h> does not always declare `uint`. We provide 93// the typedef prior to including <sys/vmount.h> to work around this issue. 94typedef uint_t uint; 95#include <sys/vmount.h> 96#else 97#include <sys/mount.h> 98#endif 99#define STATVFS statfs 100#define FSTATVFS fstatfs 101#define STATVFS_F_FRSIZE(vfs) static_cast<uint64_t>(vfs.f_bsize) 102#endif 103 104#if defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__) 105#define STATVFS_F_FLAG(vfs) (vfs).f_flag 106#else 107#define STATVFS_F_FLAG(vfs) (vfs).f_flags 108#endif 109 110using namespace llvm; 111 112namespace llvm { 113namespace sys { 114namespace fs { 115 116const file_t kInvalidFile = -1; 117 118#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ 119 defined(__minix) || defined(__FreeBSD_kernel__) || defined(__linux__) || \ 120 defined(__CYGWIN__) || defined(__DragonFly__) || defined(_AIX) || defined(__GNU__) 121static int 122test_dir(char ret[PATH_MAX], const char *dir, const char *bin) 123{ 124 struct stat sb; 125 char fullpath[PATH_MAX]; 126 127 int chars = snprintf(fullpath, PATH_MAX, "%s/%s", dir, bin); 128 // We cannot write PATH_MAX characters because the string will be terminated 129 // with a null character. Fail if truncation happened. 130 if (chars >= PATH_MAX) 131 return 1; 132 if (!realpath(fullpath, ret)) 133 return 1; 134 if (stat(fullpath, &sb) != 0) 135 return 1; 136 137 return 0; 138} 139 140static char * 141getprogpath(char ret[PATH_MAX], const char *bin) 142{ 143 /* First approach: absolute path. */ 144 if (bin[0] == '/') { 145 if (test_dir(ret, "/", bin) == 0) 146 return ret; 147 return nullptr; 148 } 149 150 /* Second approach: relative path. */ 151 if (strchr(bin, '/')) { 152 char cwd[PATH_MAX]; 153 if (!getcwd(cwd, PATH_MAX)) 154 return nullptr; 155 if (test_dir(ret, cwd, bin) == 0) 156 return ret; 157 return nullptr; 158 } 159 160 /* Third approach: $PATH */ 161 char *pv; 162 if ((pv = getenv("PATH")) == nullptr) 163 return nullptr; 164 char *s = strdup(pv); 165 if (!s) 166 return nullptr; 167 char *state; 168 for (char *t = strtok_r(s, ":", &state); t != nullptr; 169 t = strtok_r(nullptr, ":", &state)) { 170 if (test_dir(ret, t, bin) == 0) { 171 free(s); 172 return ret; 173 } 174 } 175 free(s); 176 return nullptr; 177} 178#endif // __FreeBSD__ || __NetBSD__ || __FreeBSD_kernel__ 179 180/// GetMainExecutable - Return the path to the main executable, given the 181/// value of argv[0] from program startup. 182std::string getMainExecutable(const char *argv0, void *MainAddr) { 183#if defined(__APPLE__) 184 // On OS X the executable path is saved to the stack by dyld. Reading it 185 // from there is much faster than calling dladdr, especially for large 186 // binaries with symbols. 187 char exe_path[MAXPATHLEN]; 188 uint32_t size = sizeof(exe_path); 189 if (_NSGetExecutablePath(exe_path, &size) == 0) { 190 char link_path[MAXPATHLEN]; 191 if (realpath(exe_path, link_path)) 192 return link_path; 193 } 194#elif defined(__FreeBSD__) 195 // On FreeBSD if the exec path specified in ELF auxiliary vectors is 196 // preferred, if available. /proc/curproc/file and the KERN_PROC_PATHNAME 197 // sysctl may not return the desired path if there are multiple hardlinks 198 // to the file. 199 char exe_path[PATH_MAX]; 200#if __FreeBSD_version >= 1300057 201 char exe_path[PATH_MAX]; 202 if (elf_aux_info(AT_EXECPATH, exe_path, sizeof(exe_path)) == 0) 203 return exe_path; 204#else 205 // elf_aux_info(AT_EXECPATH, ... is not available in all supported versions, 206 // fall back to finding the ELF auxiliary vectors after the process's 207 // environment. 208 char **p = ::environ; 209 while (*p++ != 0) 210 ; 211 // Iterate through auxiliary vectors for AT_EXECPATH. 212 for (;;) { 213 switch (*(uintptr_t *)p++) { 214 case AT_EXECPATH: 215 return *p; 216 case AT_NULL: 217 break; 218 } 219 p++; 220 } 221#endif 222 // Fall back to argv[0] if auxiliary vectors are not available. 223 if (getprogpath(exe_path, argv0) != NULL) 224 return exe_path; 225#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__minix) || \ 226 defined(__DragonFly__) || defined(__FreeBSD_kernel__) || defined(_AIX) 227 const char *curproc = "/proc/curproc/file"; 228 char exe_path[PATH_MAX]; 229 if (sys::fs::exists(curproc)) { 230 ssize_t len = readlink(curproc, exe_path, sizeof(exe_path)); 231 if (len > 0) { 232 // Null terminate the string for realpath. readlink never null 233 // terminates its output. 234 len = std::min(len, ssize_t(sizeof(exe_path) - 1)); 235 exe_path[len] = '\0'; 236 return exe_path; 237 } 238 } 239 // If we don't have procfs mounted, fall back to argv[0] 240 if (getprogpath(exe_path, argv0) != NULL) 241 return exe_path; 242#elif defined(__linux__) || defined(__CYGWIN__) || defined(__gnu_hurd__) 243 char exe_path[MAXPATHLEN]; 244 const char *aPath = "/proc/self/exe"; 245 if (sys::fs::exists(aPath)) { 246 // /proc is not always mounted under Linux (chroot for example). 247 ssize_t len = readlink(aPath, exe_path, sizeof(exe_path)); 248 if (len < 0) 249 return ""; 250 251 // Null terminate the string for realpath. readlink never null 252 // terminates its output. 253 len = std::min(len, ssize_t(sizeof(exe_path) - 1)); 254 exe_path[len] = '\0'; 255 256 // On Linux, /proc/self/exe always looks through symlinks. However, on 257 // GNU/Hurd, /proc/self/exe is a symlink to the path that was used to start 258 // the program, and not the eventual binary file. Therefore, call realpath 259 // so this behaves the same on all platforms. 260#if _POSIX_VERSION >= 200112 || defined(__GLIBC__) 261 if (char *real_path = realpath(exe_path, NULL)) { 262 std::string ret = std::string(real_path); 263 free(real_path); 264 return ret; 265 } 266#else 267 char real_path[MAXPATHLEN]; 268 if (realpath(exe_path, real_path)) 269 return std::string(real_path); 270#endif 271 } 272 // Fall back to the classical detection. 273 if (getprogpath(exe_path, argv0)) 274 return exe_path; 275#elif defined(HAVE_DLFCN_H) && defined(HAVE_DLADDR) 276 // Use dladdr to get executable path if available. 277 Dl_info DLInfo; 278 int err = dladdr(MainAddr, &DLInfo); 279 if (err == 0) 280 return ""; 281 282 // If the filename is a symlink, we need to resolve and return the location of 283 // the actual executable. 284 char link_path[MAXPATHLEN]; 285 if (realpath(DLInfo.dli_fname, link_path)) 286 return link_path; 287#else 288#error GetMainExecutable is not implemented on this host yet. 289#endif 290 return ""; 291} 292 293TimePoint<> basic_file_status::getLastAccessedTime() const { 294 return toTimePoint(fs_st_atime, fs_st_atime_nsec); 295} 296 297TimePoint<> basic_file_status::getLastModificationTime() const { 298 return toTimePoint(fs_st_mtime, fs_st_mtime_nsec); 299} 300 301UniqueID file_status::getUniqueID() const { 302 return UniqueID(fs_st_dev, fs_st_ino); 303} 304 305uint32_t file_status::getLinkCount() const { 306 return fs_st_nlinks; 307} 308 309ErrorOr<space_info> disk_space(const Twine &Path) { 310 struct STATVFS Vfs; 311 if (::STATVFS(const_cast<char *>(Path.str().c_str()), &Vfs)) 312 return std::error_code(errno, std::generic_category()); 313 auto FrSize = STATVFS_F_FRSIZE(Vfs); 314 space_info SpaceInfo; 315 SpaceInfo.capacity = static_cast<uint64_t>(Vfs.f_blocks) * FrSize; 316 SpaceInfo.free = static_cast<uint64_t>(Vfs.f_bfree) * FrSize; 317 SpaceInfo.available = static_cast<uint64_t>(Vfs.f_bavail) * FrSize; 318 return SpaceInfo; 319} 320 321std::error_code current_path(SmallVectorImpl<char> &result) { 322 result.clear(); 323 324 const char *pwd = ::getenv("PWD"); 325 llvm::sys::fs::file_status PWDStatus, DotStatus; 326 if (pwd && llvm::sys::path::is_absolute(pwd) && 327 !llvm::sys::fs::status(pwd, PWDStatus) && 328 !llvm::sys::fs::status(".", DotStatus) && 329 PWDStatus.getUniqueID() == DotStatus.getUniqueID()) { 330 result.append(pwd, pwd + strlen(pwd)); 331 return std::error_code(); 332 } 333 334#ifdef MAXPATHLEN 335 result.reserve(MAXPATHLEN); 336#else 337// For GNU Hurd 338 result.reserve(1024); 339#endif 340 341 while (true) { 342 if (::getcwd(result.data(), result.capacity()) == nullptr) { 343 // See if there was a real error. 344 if (errno != ENOMEM) 345 return std::error_code(errno, std::generic_category()); 346 // Otherwise there just wasn't enough space. 347 result.reserve(result.capacity() * 2); 348 } else 349 break; 350 } 351 352 result.set_size(strlen(result.data())); 353 return std::error_code(); 354} 355 356std::error_code set_current_path(const Twine &path) { 357 SmallString<128> path_storage; 358 StringRef p = path.toNullTerminatedStringRef(path_storage); 359 360 if (::chdir(p.begin()) == -1) 361 return std::error_code(errno, std::generic_category()); 362 363 return std::error_code(); 364} 365 366std::error_code create_directory(const Twine &path, bool IgnoreExisting, 367 perms Perms) { 368 SmallString<128> path_storage; 369 StringRef p = path.toNullTerminatedStringRef(path_storage); 370 371 if (::mkdir(p.begin(), Perms) == -1) { 372 if (errno != EEXIST || !IgnoreExisting) 373 return std::error_code(errno, std::generic_category()); 374 } 375 376 return std::error_code(); 377} 378 379// Note that we are using symbolic link because hard links are not supported by 380// all filesystems (SMB doesn't). 381std::error_code create_link(const Twine &to, const Twine &from) { 382 // Get arguments. 383 SmallString<128> from_storage; 384 SmallString<128> to_storage; 385 StringRef f = from.toNullTerminatedStringRef(from_storage); 386 StringRef t = to.toNullTerminatedStringRef(to_storage); 387 388 if (::symlink(t.begin(), f.begin()) == -1) 389 return std::error_code(errno, std::generic_category()); 390 391 return std::error_code(); 392} 393 394std::error_code create_hard_link(const Twine &to, const Twine &from) { 395 // Get arguments. 396 SmallString<128> from_storage; 397 SmallString<128> to_storage; 398 StringRef f = from.toNullTerminatedStringRef(from_storage); 399 StringRef t = to.toNullTerminatedStringRef(to_storage); 400 401 if (::link(t.begin(), f.begin()) == -1) 402 return std::error_code(errno, std::generic_category()); 403 404 return std::error_code(); 405} 406 407std::error_code remove(const Twine &path, bool IgnoreNonExisting) { 408 SmallString<128> path_storage; 409 StringRef p = path.toNullTerminatedStringRef(path_storage); 410 411 struct stat buf; 412 if (lstat(p.begin(), &buf) != 0) { 413 if (errno != ENOENT || !IgnoreNonExisting) 414 return std::error_code(errno, std::generic_category()); 415 return std::error_code(); 416 } 417 418 // Note: this check catches strange situations. In all cases, LLVM should 419 // only be involved in the creation and deletion of regular files. This 420 // check ensures that what we're trying to erase is a regular file. It 421 // effectively prevents LLVM from erasing things like /dev/null, any block 422 // special file, or other things that aren't "regular" files. 423 if (!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode) && !S_ISLNK(buf.st_mode)) 424 return make_error_code(errc::operation_not_permitted); 425 426 if (::remove(p.begin()) == -1) { 427 if (errno != ENOENT || !IgnoreNonExisting) 428 return std::error_code(errno, std::generic_category()); 429 } 430 431 return std::error_code(); 432} 433 434static bool is_local_impl(struct STATVFS &Vfs) { 435#if defined(__linux__) || defined(__GNU__) 436#ifndef NFS_SUPER_MAGIC 437#define NFS_SUPER_MAGIC 0x6969 438#endif 439#ifndef SMB_SUPER_MAGIC 440#define SMB_SUPER_MAGIC 0x517B 441#endif 442#ifndef CIFS_MAGIC_NUMBER 443#define CIFS_MAGIC_NUMBER 0xFF534D42 444#endif 445#ifdef __GNU__ 446 switch ((uint32_t)Vfs.__f_type) { 447#else 448 switch ((uint32_t)Vfs.f_type) { 449#endif 450 case NFS_SUPER_MAGIC: 451 case SMB_SUPER_MAGIC: 452 case CIFS_MAGIC_NUMBER: 453 return false; 454 default: 455 return true; 456 } 457#elif defined(__CYGWIN__) 458 // Cygwin doesn't expose this information; would need to use Win32 API. 459 return false; 460#elif defined(__Fuchsia__) 461 // Fuchsia doesn't yet support remote filesystem mounts. 462 return true; 463#elif defined(__EMSCRIPTEN__) 464 // Emscripten doesn't currently support remote filesystem mounts. 465 return true; 466#elif defined(__HAIKU__) 467 // Haiku doesn't expose this information. 468 return false; 469#elif defined(__sun) 470 // statvfs::f_basetype contains a null-terminated FSType name of the mounted target 471 StringRef fstype(Vfs.f_basetype); 472 // NFS is the only non-local fstype?? 473 return !fstype.equals("nfs"); 474#elif defined(_AIX) 475 // Call mntctl; try more than twice in case of timing issues with a concurrent 476 // mount. 477 int Ret; 478 size_t BufSize = 2048u; 479 std::unique_ptr<char[]> Buf; 480 int Tries = 3; 481 while (Tries--) { 482 Buf = std::make_unique<char[]>(BufSize); 483 Ret = mntctl(MCTL_QUERY, BufSize, Buf.get()); 484 if (Ret != 0) 485 break; 486 BufSize = *reinterpret_cast<unsigned int *>(Buf.get()); 487 Buf.reset(); 488 } 489 490 if (Ret == -1) 491 // There was an error; "remote" is the conservative answer. 492 return false; 493 494 // Look for the correct vmount entry. 495 char *CurObjPtr = Buf.get(); 496 while (Ret--) { 497 struct vmount *Vp = reinterpret_cast<struct vmount *>(CurObjPtr); 498 static_assert(sizeof(Vfs.f_fsid) == sizeof(Vp->vmt_fsid), 499 "fsid length mismatch"); 500 if (memcmp(&Vfs.f_fsid, &Vp->vmt_fsid, sizeof Vfs.f_fsid) == 0) 501 return (Vp->vmt_flags & MNT_REMOTE) == 0; 502 503 CurObjPtr += Vp->vmt_length; 504 } 505 506 // vmount entry not found; "remote" is the conservative answer. 507 return false; 508#else 509 return !!(STATVFS_F_FLAG(Vfs) & MNT_LOCAL); 510#endif 511} 512 513std::error_code is_local(const Twine &Path, bool &Result) { 514 struct STATVFS Vfs; 515 if (::STATVFS(const_cast<char *>(Path.str().c_str()), &Vfs)) 516 return std::error_code(errno, std::generic_category()); 517 518 Result = is_local_impl(Vfs); 519 return std::error_code(); 520} 521 522std::error_code is_local(int FD, bool &Result) { 523 struct STATVFS Vfs; 524 if (::FSTATVFS(FD, &Vfs)) 525 return std::error_code(errno, std::generic_category()); 526 527 Result = is_local_impl(Vfs); 528 return std::error_code(); 529} 530 531std::error_code rename(const Twine &from, const Twine &to) { 532 // Get arguments. 533 SmallString<128> from_storage; 534 SmallString<128> to_storage; 535 StringRef f = from.toNullTerminatedStringRef(from_storage); 536 StringRef t = to.toNullTerminatedStringRef(to_storage); 537 538 if (::rename(f.begin(), t.begin()) == -1) 539 return std::error_code(errno, std::generic_category()); 540 541 return std::error_code(); 542} 543 544std::error_code resize_file(int FD, uint64_t Size) { 545#if defined(HAVE_POSIX_FALLOCATE) 546 // If we have posix_fallocate use it. Unlike ftruncate it always allocates 547 // space, so we get an error if the disk is full. 548 if (int Err = ::posix_fallocate(FD, 0, Size)) { 549#ifdef _AIX 550 constexpr int NotSupportedError = ENOTSUP; 551#else 552 constexpr int NotSupportedError = EOPNOTSUPP; 553#endif 554 if (Err != EINVAL && Err != NotSupportedError) 555 return std::error_code(Err, std::generic_category()); 556 } 557#endif 558 // Use ftruncate as a fallback. It may or may not allocate space. At least on 559 // OS X with HFS+ it does. 560 if (::ftruncate(FD, Size) == -1) 561 return std::error_code(errno, std::generic_category()); 562 563 return std::error_code(); 564} 565 566static int convertAccessMode(AccessMode Mode) { 567 switch (Mode) { 568 case AccessMode::Exist: 569 return F_OK; 570 case AccessMode::Write: 571 return W_OK; 572 case AccessMode::Execute: 573 return R_OK | X_OK; // scripts also need R_OK. 574 } 575 llvm_unreachable("invalid enum"); 576} 577 578std::error_code access(const Twine &Path, AccessMode Mode) { 579 SmallString<128> PathStorage; 580 StringRef P = Path.toNullTerminatedStringRef(PathStorage); 581 582 if (::access(P.begin(), convertAccessMode(Mode)) == -1) 583 return std::error_code(errno, std::generic_category()); 584 585 if (Mode == AccessMode::Execute) { 586 // Don't say that directories are executable. 587 struct stat buf; 588 if (0 != stat(P.begin(), &buf)) 589 return errc::permission_denied; 590 if (!S_ISREG(buf.st_mode)) 591 return errc::permission_denied; 592 } 593 594 return std::error_code(); 595} 596 597bool can_execute(const Twine &Path) { 598 return !access(Path, AccessMode::Execute); 599} 600 601bool equivalent(file_status A, file_status B) { 602 assert(status_known(A) && status_known(B)); 603 return A.fs_st_dev == B.fs_st_dev && 604 A.fs_st_ino == B.fs_st_ino; 605} 606 607std::error_code equivalent(const Twine &A, const Twine &B, bool &result) { 608 file_status fsA, fsB; 609 if (std::error_code ec = status(A, fsA)) 610 return ec; 611 if (std::error_code ec = status(B, fsB)) 612 return ec; 613 result = equivalent(fsA, fsB); 614 return std::error_code(); 615} 616 617static void expandTildeExpr(SmallVectorImpl<char> &Path) { 618 StringRef PathStr(Path.begin(), Path.size()); 619 if (PathStr.empty() || !PathStr.startswith("~")) 620 return; 621 622 PathStr = PathStr.drop_front(); 623 StringRef Expr = 624 PathStr.take_until([](char c) { return path::is_separator(c); }); 625 StringRef Remainder = PathStr.substr(Expr.size() + 1); 626 SmallString<128> Storage; 627 if (Expr.empty()) { 628 // This is just ~/..., resolve it to the current user's home dir. 629 if (!path::home_directory(Storage)) { 630 // For some reason we couldn't get the home directory. Just exit. 631 return; 632 } 633 634 // Overwrite the first character and insert the rest. 635 Path[0] = Storage[0]; 636 Path.insert(Path.begin() + 1, Storage.begin() + 1, Storage.end()); 637 return; 638 } 639 640 // This is a string of the form ~username/, look up this user's entry in the 641 // password database. 642 struct passwd *Entry = nullptr; 643 std::string User = Expr.str(); 644 Entry = ::getpwnam(User.c_str()); 645 646 if (!Entry) { 647 // Unable to look up the entry, just return back the original path. 648 return; 649 } 650 651 Storage = Remainder; 652 Path.clear(); 653 Path.append(Entry->pw_dir, Entry->pw_dir + strlen(Entry->pw_dir)); 654 llvm::sys::path::append(Path, Storage); 655} 656 657 658void expand_tilde(const Twine &path, SmallVectorImpl<char> &dest) { 659 dest.clear(); 660 if (path.isTriviallyEmpty()) 661 return; 662 663 path.toVector(dest); 664 expandTildeExpr(dest); 665 666 return; 667} 668 669static file_type typeForMode(mode_t Mode) { 670 if (S_ISDIR(Mode)) 671 return file_type::directory_file; 672 else if (S_ISREG(Mode)) 673 return file_type::regular_file; 674 else if (S_ISBLK(Mode)) 675 return file_type::block_file; 676 else if (S_ISCHR(Mode)) 677 return file_type::character_file; 678 else if (S_ISFIFO(Mode)) 679 return file_type::fifo_file; 680 else if (S_ISSOCK(Mode)) 681 return file_type::socket_file; 682 else if (S_ISLNK(Mode)) 683 return file_type::symlink_file; 684 return file_type::type_unknown; 685} 686 687static std::error_code fillStatus(int StatRet, const struct stat &Status, 688 file_status &Result) { 689 if (StatRet != 0) { 690 std::error_code EC(errno, std::generic_category()); 691 if (EC == errc::no_such_file_or_directory) 692 Result = file_status(file_type::file_not_found); 693 else 694 Result = file_status(file_type::status_error); 695 return EC; 696 } 697 698 uint32_t atime_nsec, mtime_nsec; 699#if defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC) 700 atime_nsec = Status.st_atimespec.tv_nsec; 701 mtime_nsec = Status.st_mtimespec.tv_nsec; 702#elif defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) 703 atime_nsec = Status.st_atim.tv_nsec; 704 mtime_nsec = Status.st_mtim.tv_nsec; 705#else 706 atime_nsec = mtime_nsec = 0; 707#endif 708 709 perms Perms = static_cast<perms>(Status.st_mode) & all_perms; 710 Result = file_status(typeForMode(Status.st_mode), Perms, Status.st_dev, 711 Status.st_nlink, Status.st_ino, 712 Status.st_atime, atime_nsec, Status.st_mtime, mtime_nsec, 713 Status.st_uid, Status.st_gid, Status.st_size); 714 715 return std::error_code(); 716} 717 718std::error_code status(const Twine &Path, file_status &Result, bool Follow) { 719 SmallString<128> PathStorage; 720 StringRef P = Path.toNullTerminatedStringRef(PathStorage); 721 722 struct stat Status; 723 int StatRet = (Follow ? ::stat : ::lstat)(P.begin(), &Status); 724 return fillStatus(StatRet, Status, Result); 725} 726 727std::error_code status(int FD, file_status &Result) { 728 struct stat Status; 729 int StatRet = ::fstat(FD, &Status); 730 return fillStatus(StatRet, Status, Result); 731} 732 733unsigned getUmask() { 734 // Chose arbitary new mask and reset the umask to the old mask. 735 // umask(2) never fails so ignore the return of the second call. 736 unsigned Mask = ::umask(0); 737 (void) ::umask(Mask); 738 return Mask; 739} 740 741std::error_code setPermissions(const Twine &Path, perms Permissions) { 742 SmallString<128> PathStorage; 743 StringRef P = Path.toNullTerminatedStringRef(PathStorage); 744 745 if (::chmod(P.begin(), Permissions)) 746 return std::error_code(errno, std::generic_category()); 747 return std::error_code(); 748} 749 750std::error_code setPermissions(int FD, perms Permissions) { 751 if (::fchmod(FD, Permissions)) 752 return std::error_code(errno, std::generic_category()); 753 return std::error_code(); 754} 755 756std::error_code setLastAccessAndModificationTime(int FD, TimePoint<> AccessTime, 757 TimePoint<> ModificationTime) { 758#if defined(HAVE_FUTIMENS) 759 timespec Times[2]; 760 Times[0] = sys::toTimeSpec(AccessTime); 761 Times[1] = sys::toTimeSpec(ModificationTime); 762 if (::futimens(FD, Times)) 763 return std::error_code(errno, std::generic_category()); 764 return std::error_code(); 765#elif defined(HAVE_FUTIMES) 766 timeval Times[2]; 767 Times[0] = sys::toTimeVal( 768 std::chrono::time_point_cast<std::chrono::microseconds>(AccessTime)); 769 Times[1] = 770 sys::toTimeVal(std::chrono::time_point_cast<std::chrono::microseconds>( 771 ModificationTime)); 772 if (::futimes(FD, Times)) 773 return std::error_code(errno, std::generic_category()); 774 return std::error_code(); 775#else 776#warning Missing futimes() and futimens() 777 return make_error_code(errc::function_not_supported); 778#endif 779} 780 781std::error_code mapped_file_region::init(int FD, uint64_t Offset, 782 mapmode Mode) { 783 assert(Size != 0); 784 785 int flags = (Mode == readwrite) ? MAP_SHARED : MAP_PRIVATE; 786 int prot = (Mode == readonly) ? PROT_READ : (PROT_READ | PROT_WRITE); 787#if defined(__APPLE__) 788 //---------------------------------------------------------------------- 789 // Newer versions of MacOSX have a flag that will allow us to read from 790 // binaries whose code signature is invalid without crashing by using 791 // the MAP_RESILIENT_CODESIGN flag. Also if a file from removable media 792 // is mapped we can avoid crashing and return zeroes to any pages we try 793 // to read if the media becomes unavailable by using the 794 // MAP_RESILIENT_MEDIA flag. These flags are only usable when mapping 795 // with PROT_READ, so take care not to specify them otherwise. 796 //---------------------------------------------------------------------- 797 if (Mode == readonly) { 798#if defined(MAP_RESILIENT_CODESIGN) 799 flags |= MAP_RESILIENT_CODESIGN; 800#endif 801#if defined(MAP_RESILIENT_MEDIA) 802 flags |= MAP_RESILIENT_MEDIA; 803#endif 804 } 805#endif // #if defined (__APPLE__) 806 807 Mapping = ::mmap(nullptr, Size, prot, flags, FD, Offset); 808 if (Mapping == MAP_FAILED) 809 return std::error_code(errno, std::generic_category()); 810 return std::error_code(); 811} 812 813mapped_file_region::mapped_file_region(int fd, mapmode mode, size_t length, 814 uint64_t offset, std::error_code &ec) 815 : Size(length), Mapping(), Mode(mode) { 816 (void)Mode; 817 ec = init(fd, offset, mode); 818 if (ec) 819 Mapping = nullptr; 820} 821 822mapped_file_region::~mapped_file_region() { 823 if (Mapping) 824 ::munmap(Mapping, Size); 825} 826 827size_t mapped_file_region::size() const { 828 assert(Mapping && "Mapping failed but used anyway!"); 829 return Size; 830} 831 832char *mapped_file_region::data() const { 833 assert(Mapping && "Mapping failed but used anyway!"); 834 return reinterpret_cast<char*>(Mapping); 835} 836 837const char *mapped_file_region::const_data() const { 838 assert(Mapping && "Mapping failed but used anyway!"); 839 return reinterpret_cast<const char*>(Mapping); 840} 841 842int mapped_file_region::alignment() { 843 return Process::getPageSizeEstimate(); 844} 845 846std::error_code detail::directory_iterator_construct(detail::DirIterState &it, 847 StringRef path, 848 bool follow_symlinks) { 849 SmallString<128> path_null(path); 850 DIR *directory = ::opendir(path_null.c_str()); 851 if (!directory) 852 return std::error_code(errno, std::generic_category()); 853 854 it.IterationHandle = reinterpret_cast<intptr_t>(directory); 855 // Add something for replace_filename to replace. 856 path::append(path_null, "."); 857 it.CurrentEntry = directory_entry(path_null.str(), follow_symlinks); 858 return directory_iterator_increment(it); 859} 860 861std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) { 862 if (it.IterationHandle) 863 ::closedir(reinterpret_cast<DIR *>(it.IterationHandle)); 864 it.IterationHandle = 0; 865 it.CurrentEntry = directory_entry(); 866 return std::error_code(); 867} 868 869static file_type direntType(dirent* Entry) { 870 // Most platforms provide the file type in the dirent: Linux/BSD/Mac. 871 // The DTTOIF macro lets us reuse our status -> type conversion. 872 // Note that while glibc provides a macro to see if this is supported, 873 // _DIRENT_HAVE_D_TYPE, it's not defined on BSD/Mac, so we test for the 874 // d_type-to-mode_t conversion macro instead. 875#if defined(DTTOIF) 876 return typeForMode(DTTOIF(Entry->d_type)); 877#else 878 // Other platforms such as Solaris require a stat() to get the type. 879 return file_type::type_unknown; 880#endif 881} 882 883std::error_code detail::directory_iterator_increment(detail::DirIterState &It) { 884 errno = 0; 885 dirent *CurDir = ::readdir(reinterpret_cast<DIR *>(It.IterationHandle)); 886 if (CurDir == nullptr && errno != 0) { 887 return std::error_code(errno, std::generic_category()); 888 } else if (CurDir != nullptr) { 889 StringRef Name(CurDir->d_name); 890 if ((Name.size() == 1 && Name[0] == '.') || 891 (Name.size() == 2 && Name[0] == '.' && Name[1] == '.')) 892 return directory_iterator_increment(It); 893 It.CurrentEntry.replace_filename(Name, direntType(CurDir)); 894 } else 895 return directory_iterator_destruct(It); 896 897 return std::error_code(); 898} 899 900ErrorOr<basic_file_status> directory_entry::status() const { 901 file_status s; 902 if (auto EC = fs::status(Path, s, FollowSymlinks)) 903 return EC; 904 return s; 905} 906 907#if !defined(F_GETPATH) 908static bool hasProcSelfFD() { 909 // If we have a /proc filesystem mounted, we can quickly establish the 910 // real name of the file with readlink 911 static const bool Result = (::access("/proc/self/fd", R_OK) == 0); 912 return Result; 913} 914#endif 915 916static int nativeOpenFlags(CreationDisposition Disp, OpenFlags Flags, 917 FileAccess Access) { 918 int Result = 0; 919 if (Access == FA_Read) 920 Result |= O_RDONLY; 921 else if (Access == FA_Write) 922 Result |= O_WRONLY; 923 else if (Access == (FA_Read | FA_Write)) 924 Result |= O_RDWR; 925 926 // This is for compatibility with old code that assumed OF_Append implied 927 // would open an existing file. See Windows/Path.inc for a longer comment. 928 if (Flags & OF_Append) 929 Disp = CD_OpenAlways; 930 931 if (Disp == CD_CreateNew) { 932 Result |= O_CREAT; // Create if it doesn't exist. 933 Result |= O_EXCL; // Fail if it does. 934 } else if (Disp == CD_CreateAlways) { 935 Result |= O_CREAT; // Create if it doesn't exist. 936 Result |= O_TRUNC; // Truncate if it does. 937 } else if (Disp == CD_OpenAlways) { 938 Result |= O_CREAT; // Create if it doesn't exist. 939 } else if (Disp == CD_OpenExisting) { 940 // Nothing special, just don't add O_CREAT and we get these semantics. 941 } 942 943 if (Flags & OF_Append) 944 Result |= O_APPEND; 945 946#ifdef O_CLOEXEC 947 if (!(Flags & OF_ChildInherit)) 948 Result |= O_CLOEXEC; 949#endif 950 951 return Result; 952} 953 954std::error_code openFile(const Twine &Name, int &ResultFD, 955 CreationDisposition Disp, FileAccess Access, 956 OpenFlags Flags, unsigned Mode) { 957 int OpenFlags = nativeOpenFlags(Disp, Flags, Access); 958 959 SmallString<128> Storage; 960 StringRef P = Name.toNullTerminatedStringRef(Storage); 961 // Call ::open in a lambda to avoid overload resolution in RetryAfterSignal 962 // when open is overloaded, such as in Bionic. 963 auto Open = [&]() { return ::open(P.begin(), OpenFlags, Mode); }; 964 if ((ResultFD = sys::RetryAfterSignal(-1, Open)) < 0) 965 return std::error_code(errno, std::generic_category()); 966#ifndef O_CLOEXEC 967 if (!(Flags & OF_ChildInherit)) { 968 int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC); 969 (void)r; 970 assert(r == 0 && "fcntl(F_SETFD, FD_CLOEXEC) failed"); 971 } 972#endif 973 return std::error_code(); 974} 975 976Expected<int> openNativeFile(const Twine &Name, CreationDisposition Disp, 977 FileAccess Access, OpenFlags Flags, 978 unsigned Mode) { 979 980 int FD; 981 std::error_code EC = openFile(Name, FD, Disp, Access, Flags, Mode); 982 if (EC) 983 return errorCodeToError(EC); 984 return FD; 985} 986 987std::error_code openFileForRead(const Twine &Name, int &ResultFD, 988 OpenFlags Flags, 989 SmallVectorImpl<char> *RealPath) { 990 std::error_code EC = 991 openFile(Name, ResultFD, CD_OpenExisting, FA_Read, Flags, 0666); 992 if (EC) 993 return EC; 994 995 // Attempt to get the real name of the file, if the user asked 996 if(!RealPath) 997 return std::error_code(); 998 RealPath->clear(); 999#if defined(F_GETPATH) 1000 // When F_GETPATH is availble, it is the quickest way to get 1001 // the real path name. 1002 char Buffer[MAXPATHLEN]; 1003 if (::fcntl(ResultFD, F_GETPATH, Buffer) != -1) 1004 RealPath->append(Buffer, Buffer + strlen(Buffer)); 1005#else 1006 char Buffer[PATH_MAX]; 1007 if (hasProcSelfFD()) { 1008 char ProcPath[64]; 1009 snprintf(ProcPath, sizeof(ProcPath), "/proc/self/fd/%d", ResultFD); 1010 ssize_t CharCount = ::readlink(ProcPath, Buffer, sizeof(Buffer)); 1011 if (CharCount > 0) 1012 RealPath->append(Buffer, Buffer + CharCount); 1013 } else { 1014 SmallString<128> Storage; 1015 StringRef P = Name.toNullTerminatedStringRef(Storage); 1016 1017 // Use ::realpath to get the real path name 1018 if (::realpath(P.begin(), Buffer) != nullptr) 1019 RealPath->append(Buffer, Buffer + strlen(Buffer)); 1020 } 1021#endif 1022 return std::error_code(); 1023} 1024 1025Expected<file_t> openNativeFileForRead(const Twine &Name, OpenFlags Flags, 1026 SmallVectorImpl<char> *RealPath) { 1027 file_t ResultFD; 1028 std::error_code EC = openFileForRead(Name, ResultFD, Flags, RealPath); 1029 if (EC) 1030 return errorCodeToError(EC); 1031 return ResultFD; 1032} 1033 1034file_t getStdinHandle() { return 0; } 1035file_t getStdoutHandle() { return 1; } 1036file_t getStderrHandle() { return 2; } 1037 1038Expected<size_t> readNativeFile(file_t FD, MutableArrayRef<char> Buf) { 1039 ssize_t NumRead = 1040 sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Buf.size()); 1041 if (ssize_t(NumRead) == -1) 1042 return errorCodeToError(std::error_code(errno, std::generic_category())); 1043 return NumRead; 1044} 1045 1046Expected<size_t> readNativeFileSlice(file_t FD, MutableArrayRef<char> Buf, 1047 uint64_t Offset) { 1048#ifdef HAVE_PREAD 1049 ssize_t NumRead = 1050 sys::RetryAfterSignal(-1, ::pread, FD, Buf.data(), Buf.size(), Offset); 1051#else 1052 if (lseek(FD, Offset, SEEK_SET) == -1) 1053 return errorCodeToError(std::error_code(errno, std::generic_category())); 1054 ssize_t NumRead = 1055 sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Buf.size()); 1056#endif 1057 if (NumRead == -1) 1058 return errorCodeToError(std::error_code(errno, std::generic_category())); 1059 return NumRead; 1060} 1061 1062std::error_code closeFile(file_t &F) { 1063 file_t TmpF = F; 1064 F = kInvalidFile; 1065 return Process::SafelyCloseFileDescriptor(TmpF); 1066} 1067 1068template <typename T> 1069static std::error_code remove_directories_impl(const T &Entry, 1070 bool IgnoreErrors) { 1071 std::error_code EC; 1072 directory_iterator Begin(Entry, EC, false); 1073 directory_iterator End; 1074 while (Begin != End) { 1075 auto &Item = *Begin; 1076 ErrorOr<basic_file_status> st = Item.status(); 1077 if (!st && !IgnoreErrors) 1078 return st.getError(); 1079 1080 if (is_directory(*st)) { 1081 EC = remove_directories_impl(Item, IgnoreErrors); 1082 if (EC && !IgnoreErrors) 1083 return EC; 1084 } 1085 1086 EC = fs::remove(Item.path(), true); 1087 if (EC && !IgnoreErrors) 1088 return EC; 1089 1090 Begin.increment(EC); 1091 if (EC && !IgnoreErrors) 1092 return EC; 1093 } 1094 return std::error_code(); 1095} 1096 1097std::error_code remove_directories(const Twine &path, bool IgnoreErrors) { 1098 auto EC = remove_directories_impl(path, IgnoreErrors); 1099 if (EC && !IgnoreErrors) 1100 return EC; 1101 EC = fs::remove(path, true); 1102 if (EC && !IgnoreErrors) 1103 return EC; 1104 return std::error_code(); 1105} 1106 1107std::error_code real_path(const Twine &path, SmallVectorImpl<char> &dest, 1108 bool expand_tilde) { 1109 dest.clear(); 1110 if (path.isTriviallyEmpty()) 1111 return std::error_code(); 1112 1113 if (expand_tilde) { 1114 SmallString<128> Storage; 1115 path.toVector(Storage); 1116 expandTildeExpr(Storage); 1117 return real_path(Storage, dest, false); 1118 } 1119 1120 SmallString<128> Storage; 1121 StringRef P = path.toNullTerminatedStringRef(Storage); 1122 char Buffer[PATH_MAX]; 1123 if (::realpath(P.begin(), Buffer) == nullptr) 1124 return std::error_code(errno, std::generic_category()); 1125 dest.append(Buffer, Buffer + strlen(Buffer)); 1126 return std::error_code(); 1127} 1128 1129} // end namespace fs 1130 1131namespace path { 1132 1133bool home_directory(SmallVectorImpl<char> &result) { 1134 char *RequestedDir = getenv("HOME"); 1135 if (!RequestedDir) { 1136 struct passwd *pw = getpwuid(getuid()); 1137 if (pw && pw->pw_dir) 1138 RequestedDir = pw->pw_dir; 1139 } 1140 if (!RequestedDir) 1141 return false; 1142 1143 result.clear(); 1144 result.append(RequestedDir, RequestedDir + strlen(RequestedDir)); 1145 return true; 1146} 1147 1148static bool getDarwinConfDir(bool TempDir, SmallVectorImpl<char> &Result) { 1149 #if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR) 1150 // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR. 1151 // macros defined in <unistd.h> on darwin >= 9 1152 int ConfName = TempDir ? _CS_DARWIN_USER_TEMP_DIR 1153 : _CS_DARWIN_USER_CACHE_DIR; 1154 size_t ConfLen = confstr(ConfName, nullptr, 0); 1155 if (ConfLen > 0) { 1156 do { 1157 Result.resize(ConfLen); 1158 ConfLen = confstr(ConfName, Result.data(), Result.size()); 1159 } while (ConfLen > 0 && ConfLen != Result.size()); 1160 1161 if (ConfLen > 0) { 1162 assert(Result.back() == 0); 1163 Result.pop_back(); 1164 return true; 1165 } 1166 1167 Result.clear(); 1168 } 1169 #endif 1170 return false; 1171} 1172 1173static const char *getEnvTempDir() { 1174 // Check whether the temporary directory is specified by an environment 1175 // variable. 1176 const char *EnvironmentVariables[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"}; 1177 for (const char *Env : EnvironmentVariables) { 1178 if (const char *Dir = std::getenv(Env)) 1179 return Dir; 1180 } 1181 1182 return nullptr; 1183} 1184 1185static const char *getDefaultTempDir(bool ErasedOnReboot) { 1186#ifdef P_tmpdir 1187 if ((bool)P_tmpdir) 1188 return P_tmpdir; 1189#endif 1190 1191 if (ErasedOnReboot) 1192 return "/tmp"; 1193 return "/var/tmp"; 1194} 1195 1196void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl<char> &Result) { 1197 Result.clear(); 1198 1199 if (ErasedOnReboot) { 1200 // There is no env variable for the cache directory. 1201 if (const char *RequestedDir = getEnvTempDir()) { 1202 Result.append(RequestedDir, RequestedDir + strlen(RequestedDir)); 1203 return; 1204 } 1205 } 1206 1207 if (getDarwinConfDir(ErasedOnReboot, Result)) 1208 return; 1209 1210 const char *RequestedDir = getDefaultTempDir(ErasedOnReboot); 1211 Result.append(RequestedDir, RequestedDir + strlen(RequestedDir)); 1212} 1213 1214} // end namespace path 1215 1216namespace fs { 1217 1218#ifdef __APPLE__ 1219/// This implementation tries to perform an APFS CoW clone of the file, 1220/// which can be much faster and uses less space. 1221/// Unfortunately fcopyfile(3) does not support COPYFILE_CLONE, so the 1222/// file descriptor variant of this function still uses the default 1223/// implementation. 1224std::error_code copy_file(const Twine &From, const Twine &To) { 1225 uint32_t Flag = COPYFILE_DATA; 1226#if __has_builtin(__builtin_available) && defined(COPYFILE_CLONE) 1227 if (__builtin_available(macos 10.12, *)) { 1228 bool IsSymlink; 1229 if (std::error_code Error = is_symlink_file(From, IsSymlink)) 1230 return Error; 1231 // COPYFILE_CLONE clones the symlink instead of following it 1232 // and returns EEXISTS if the target file already exists. 1233 if (!IsSymlink && !exists(To)) 1234 Flag = COPYFILE_CLONE; 1235 } 1236#endif 1237 int Status = 1238 copyfile(From.str().c_str(), To.str().c_str(), /* State */ NULL, Flag); 1239 1240 if (Status == 0) 1241 return std::error_code(); 1242 return std::error_code(errno, std::generic_category()); 1243} 1244#endif // __APPLE__ 1245 1246} // end namespace fs 1247 1248} // end namespace sys 1249} // end namespace llvm 1250