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