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