1//===- llvm/Support/Unix/Path.cpp - 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 portion of the Path class. 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#if HAVE_SYS_STAT_H 21#include <sys/stat.h> 22#endif 23#if HAVE_FCNTL_H 24#include <fcntl.h> 25#endif 26#ifdef HAVE_SYS_MMAN_H 27#include <sys/mman.h> 28#endif 29#ifdef HAVE_SYS_STAT_H 30#include <sys/stat.h> 31#endif 32#if HAVE_UTIME_H 33#include <utime.h> 34#endif 35#if HAVE_TIME_H 36#include <time.h> 37#endif 38#if HAVE_DIRENT_H 39# include <dirent.h> 40# define NAMLEN(dirent) strlen((dirent)->d_name) 41#else 42# define dirent direct 43# define NAMLEN(dirent) (dirent)->d_namlen 44# if HAVE_SYS_NDIR_H 45# include <sys/ndir.h> 46# endif 47# if HAVE_SYS_DIR_H 48# include <sys/dir.h> 49# endif 50# if HAVE_NDIR_H 51# include <ndir.h> 52# endif 53#endif 54 55#if HAVE_DLFCN_H 56#include <dlfcn.h> 57#endif 58 59#ifdef __APPLE__ 60#include <mach-o/dyld.h> 61#endif 62 63// For GNU Hurd 64#if defined(__GNU__) && !defined(MAXPATHLEN) 65# define MAXPATHLEN 4096 66#endif 67 68// Put in a hack for Cygwin which falsely reports that the mkdtemp function 69// is available when it is not. 70#ifdef __CYGWIN__ 71# undef HAVE_MKDTEMP 72#endif 73 74namespace { 75inline bool lastIsSlash(const std::string& path) { 76 return !path.empty() && path[path.length() - 1] == '/'; 77} 78 79} 80 81namespace llvm { 82using namespace sys; 83 84const char sys::PathSeparator = ':'; 85 86StringRef Path::GetEXESuffix() { 87 return StringRef(); 88} 89 90Path::Path(StringRef p) 91 : path(p) {} 92 93Path::Path(const char *StrStart, unsigned StrLen) 94 : path(StrStart, StrLen) {} 95 96Path& 97Path::operator=(StringRef that) { 98 path.assign(that.data(), that.size()); 99 return *this; 100} 101 102bool 103Path::isValid() const { 104 // Empty paths are considered invalid here. 105 // This code doesn't check MAXPATHLEN because there's no need. Nothing in 106 // LLVM manipulates Paths with fixed-sizes arrays, and if the OS can't 107 // handle names longer than some limit, it'll report this on demand using 108 // ENAMETOLONG. 109 return !path.empty(); 110} 111 112Path 113Path::GetTemporaryDirectory(std::string *ErrMsg) { 114#if defined(HAVE_MKDTEMP) 115 // The best way is with mkdtemp but that's not available on many systems, 116 // Linux and FreeBSD have it. Others probably won't. 117 char pathname[] = "/tmp/llvm_XXXXXX"; 118 if (0 == mkdtemp(pathname)) { 119 MakeErrMsg(ErrMsg, 120 std::string(pathname) + ": can't create temporary directory"); 121 return Path(); 122 } 123 return Path(pathname); 124#elif defined(HAVE_MKSTEMP) 125 // If no mkdtemp is available, mkstemp can be used to create a temporary file 126 // which is then removed and created as a directory. We prefer this over 127 // mktemp because of mktemp's inherent security and threading risks. We still 128 // have a slight race condition from the time the temporary file is created to 129 // the time it is re-created as a directoy. 130 char pathname[] = "/tmp/llvm_XXXXXX"; 131 int fd = 0; 132 if (-1 == (fd = mkstemp(pathname))) { 133 MakeErrMsg(ErrMsg, 134 std::string(pathname) + ": can't create temporary directory"); 135 return Path(); 136 } 137 ::close(fd); 138 ::unlink(pathname); // start race condition, ignore errors 139 if (-1 == ::mkdir(pathname, S_IRWXU)) { // end race condition 140 MakeErrMsg(ErrMsg, 141 std::string(pathname) + ": can't create temporary directory"); 142 return Path(); 143 } 144 return Path(pathname); 145#elif defined(HAVE_MKTEMP) 146 // If a system doesn't have mkdtemp(3) or mkstemp(3) but it does have 147 // mktemp(3) then we'll assume that system (e.g. AIX) has a reasonable 148 // implementation of mktemp(3) and doesn't follow BSD 4.3's lead of replacing 149 // the XXXXXX with the pid of the process and a letter. That leads to only 150 // twenty six temporary files that can be generated. 151 char pathname[] = "/tmp/llvm_XXXXXX"; 152 char *TmpName = ::mktemp(pathname); 153 if (TmpName == 0) { 154 MakeErrMsg(ErrMsg, 155 std::string(TmpName) + ": can't create unique directory name"); 156 return Path(); 157 } 158 if (-1 == ::mkdir(TmpName, S_IRWXU)) { 159 MakeErrMsg(ErrMsg, 160 std::string(TmpName) + ": can't create temporary directory"); 161 return Path(); 162 } 163 return Path(TmpName); 164#else 165 // This is the worst case implementation. tempnam(3) leaks memory unless its 166 // on an SVID2 (or later) system. On BSD 4.3 it leaks. tmpnam(3) has thread 167 // issues. The mktemp(3) function doesn't have enough variability in the 168 // temporary name generated. So, we provide our own implementation that 169 // increments an integer from a random number seeded by the current time. This 170 // should be sufficiently unique that we don't have many collisions between 171 // processes. Generally LLVM processes don't run very long and don't use very 172 // many temporary files so this shouldn't be a big issue for LLVM. 173 static time_t num = ::time(0); 174 char pathname[MAXPATHLEN]; 175 do { 176 num++; 177 sprintf(pathname, "/tmp/llvm_%010u", unsigned(num)); 178 } while ( 0 == access(pathname, F_OK ) ); 179 if (-1 == ::mkdir(pathname, S_IRWXU)) { 180 MakeErrMsg(ErrMsg, 181 std::string(pathname) + ": can't create temporary directory"); 182 return Path(); 183 } 184 return Path(pathname); 185#endif 186} 187 188Path 189Path::GetCurrentDirectory() { 190 char pathname[MAXPATHLEN]; 191 if (!getcwd(pathname, MAXPATHLEN)) { 192 assert(false && "Could not query current working directory."); 193 return Path(); 194 } 195 196 return Path(pathname); 197} 198 199#if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \ 200 defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__) || \ 201 defined(__linux__) || defined(__CYGWIN__) 202static int 203test_dir(char buf[PATH_MAX], char ret[PATH_MAX], 204 const char *dir, const char *bin) 205{ 206 struct stat sb; 207 208 snprintf(buf, PATH_MAX, "%s/%s", dir, bin); 209 if (realpath(buf, ret) == NULL) 210 return (1); 211 if (stat(buf, &sb) != 0) 212 return (1); 213 214 return (0); 215} 216 217static char * 218getprogpath(char ret[PATH_MAX], const char *bin) 219{ 220 char *pv, *s, *t, buf[PATH_MAX]; 221 222 /* First approach: absolute path. */ 223 if (bin[0] == '/') { 224 if (test_dir(buf, ret, "/", bin) == 0) 225 return (ret); 226 return (NULL); 227 } 228 229 /* Second approach: relative path. */ 230 if (strchr(bin, '/') != NULL) { 231 if (getcwd(buf, PATH_MAX) == NULL) 232 return (NULL); 233 if (test_dir(buf, ret, buf, bin) == 0) 234 return (ret); 235 return (NULL); 236 } 237 238 /* Third approach: $PATH */ 239 if ((pv = getenv("PATH")) == NULL) 240 return (NULL); 241 s = pv = strdup(pv); 242 if (pv == NULL) 243 return (NULL); 244 while ((t = strsep(&s, ":")) != NULL) { 245 if (test_dir(buf, ret, t, bin) == 0) { 246 free(pv); 247 return (ret); 248 } 249 } 250 free(pv); 251 return (NULL); 252} 253#endif // __FreeBSD__ || __NetBSD__ || __FreeBSD_kernel__ 254 255/// GetMainExecutable - Return the path to the main executable, given the 256/// value of argv[0] from program startup. 257Path Path::GetMainExecutable(const char *argv0, void *MainAddr) { 258#if defined(__APPLE__) 259 // On OS X the executable path is saved to the stack by dyld. Reading it 260 // from there is much faster than calling dladdr, especially for large 261 // binaries with symbols. 262 char exe_path[MAXPATHLEN]; 263 uint32_t size = sizeof(exe_path); 264 if (_NSGetExecutablePath(exe_path, &size) == 0) { 265 char link_path[MAXPATHLEN]; 266 if (realpath(exe_path, link_path)) 267 return Path(link_path); 268 } 269#elif defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \ 270 defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__) 271 char exe_path[PATH_MAX]; 272 273 if (getprogpath(exe_path, argv0) != NULL) 274 return Path(exe_path); 275#elif defined(__linux__) || defined(__CYGWIN__) 276 char exe_path[MAXPATHLEN]; 277 StringRef aPath("/proc/self/exe"); 278 if (sys::fs::exists(aPath)) { 279 // /proc is not always mounted under Linux (chroot for example). 280 ssize_t len = readlink(aPath.str().c_str(), exe_path, sizeof(exe_path)); 281 if (len >= 0) 282 return Path(StringRef(exe_path, len)); 283 } else { 284 // Fall back to the classical detection. 285 if (getprogpath(exe_path, argv0) != NULL) 286 return Path(exe_path); 287 } 288#elif defined(HAVE_DLFCN_H) 289 // Use dladdr to get executable path if available. 290 Dl_info DLInfo; 291 int err = dladdr(MainAddr, &DLInfo); 292 if (err == 0) 293 return Path(); 294 295 // If the filename is a symlink, we need to resolve and return the location of 296 // the actual executable. 297 char link_path[MAXPATHLEN]; 298 if (realpath(DLInfo.dli_fname, link_path)) 299 return Path(link_path); 300#else 301#error GetMainExecutable is not implemented on this host yet. 302#endif 303 return Path(); 304} 305 306bool 307Path::exists() const { 308 return 0 == access(path.c_str(), F_OK ); 309} 310 311bool 312Path::isDirectory() const { 313 struct stat buf; 314 if (0 != stat(path.c_str(), &buf)) 315 return false; 316 return ((buf.st_mode & S_IFMT) == S_IFDIR) ? true : false; 317} 318 319bool 320Path::isSymLink() const { 321 struct stat buf; 322 if (0 != lstat(path.c_str(), &buf)) 323 return false; 324 return S_ISLNK(buf.st_mode); 325} 326 327 328bool 329Path::canRead() const { 330 return 0 == access(path.c_str(), R_OK); 331} 332 333bool 334Path::canWrite() const { 335 return 0 == access(path.c_str(), W_OK); 336} 337 338bool 339Path::isRegularFile() const { 340 // Get the status so we can determine if it's a file or directory 341 struct stat buf; 342 343 if (0 != stat(path.c_str(), &buf)) 344 return false; 345 346 if (S_ISREG(buf.st_mode)) 347 return true; 348 349 return false; 350} 351 352bool 353Path::canExecute() const { 354 if (0 != access(path.c_str(), R_OK | X_OK )) 355 return false; 356 struct stat buf; 357 if (0 != stat(path.c_str(), &buf)) 358 return false; 359 if (!S_ISREG(buf.st_mode)) 360 return false; 361 return true; 362} 363 364const FileStatus * 365PathWithStatus::getFileStatus(bool update, std::string *ErrStr) const { 366 if (!fsIsValid || update) { 367 struct stat buf; 368 if (0 != stat(path.c_str(), &buf)) { 369 MakeErrMsg(ErrStr, path + ": can't get status of file"); 370 return 0; 371 } 372 status.fileSize = buf.st_size; 373 status.modTime.fromEpochTime(buf.st_mtime); 374 status.mode = buf.st_mode; 375 status.user = buf.st_uid; 376 status.group = buf.st_gid; 377 status.uniqueID = uint64_t(buf.st_ino); 378 status.isDir = S_ISDIR(buf.st_mode); 379 status.isFile = S_ISREG(buf.st_mode); 380 fsIsValid = true; 381 } 382 return &status; 383} 384 385static bool AddPermissionBits(const Path &File, int bits) { 386 // Get the umask value from the operating system. We want to use it 387 // when changing the file's permissions. Since calling umask() sets 388 // the umask and returns its old value, we must call it a second 389 // time to reset it to the user's preference. 390 int mask = umask(0777); // The arg. to umask is arbitrary. 391 umask(mask); // Restore the umask. 392 393 // Get the file's current mode. 394 struct stat buf; 395 if (0 != stat(File.c_str(), &buf)) 396 return false; 397 // Change the file to have whichever permissions bits from 'bits' 398 // that the umask would not disable. 399 if ((chmod(File.c_str(), (buf.st_mode | (bits & ~mask)))) == -1) 400 return false; 401 return true; 402} 403 404bool Path::makeReadableOnDisk(std::string* ErrMsg) { 405 if (!AddPermissionBits(*this, 0444)) 406 return MakeErrMsg(ErrMsg, path + ": can't make file readable"); 407 return false; 408} 409 410bool Path::makeWriteableOnDisk(std::string* ErrMsg) { 411 if (!AddPermissionBits(*this, 0222)) 412 return MakeErrMsg(ErrMsg, path + ": can't make file writable"); 413 return false; 414} 415 416bool 417Path::getDirectoryContents(std::set<Path>& result, std::string* ErrMsg) const { 418 DIR* direntries = ::opendir(path.c_str()); 419 if (direntries == 0) 420 return MakeErrMsg(ErrMsg, path + ": can't open directory"); 421 422 std::string dirPath = path; 423 if (!lastIsSlash(dirPath)) 424 dirPath += '/'; 425 426 result.clear(); 427 struct dirent* de = ::readdir(direntries); 428 for ( ; de != 0; de = ::readdir(direntries)) { 429 if (de->d_name[0] != '.') { 430 Path aPath(dirPath + (const char*)de->d_name); 431 struct stat st; 432 if (0 != lstat(aPath.path.c_str(), &st)) { 433 if (S_ISLNK(st.st_mode)) 434 continue; // dangling symlink -- ignore 435 return MakeErrMsg(ErrMsg, 436 aPath.path + ": can't determine file object type"); 437 } 438 result.insert(aPath); 439 } 440 } 441 442 closedir(direntries); 443 return false; 444} 445 446bool 447Path::set(StringRef a_path) { 448 if (a_path.empty()) 449 return false; 450 path = a_path; 451 return true; 452} 453 454bool 455Path::appendComponent(StringRef name) { 456 if (name.empty()) 457 return false; 458 if (!lastIsSlash(path)) 459 path += '/'; 460 path += name; 461 return true; 462} 463 464bool 465Path::eraseComponent() { 466 size_t slashpos = path.rfind('/',path.size()); 467 if (slashpos == 0 || slashpos == std::string::npos) { 468 path.erase(); 469 return true; 470 } 471 if (slashpos == path.size() - 1) 472 slashpos = path.rfind('/',slashpos-1); 473 if (slashpos == std::string::npos) { 474 path.erase(); 475 return true; 476 } 477 path.erase(slashpos); 478 return true; 479} 480 481bool 482Path::eraseSuffix() { 483 size_t dotpos = path.rfind('.',path.size()); 484 size_t slashpos = path.rfind('/',path.size()); 485 if (dotpos != std::string::npos) { 486 if (slashpos == std::string::npos || dotpos > slashpos+1) { 487 path.erase(dotpos, path.size()-dotpos); 488 return true; 489 } 490 } 491 return false; 492} 493 494static bool createDirectoryHelper(char* beg, char* end, bool create_parents) { 495 496 if (access(beg, R_OK | W_OK) == 0) 497 return false; 498 499 if (create_parents) { 500 501 char* c = end; 502 503 for (; c != beg; --c) 504 if (*c == '/') { 505 506 // Recurse to handling the parent directory. 507 *c = '\0'; 508 bool x = createDirectoryHelper(beg, c, create_parents); 509 *c = '/'; 510 511 // Return if we encountered an error. 512 if (x) 513 return true; 514 515 break; 516 } 517 } 518 519 return mkdir(beg, S_IRWXU | S_IRWXG) != 0; 520} 521 522bool 523Path::createDirectoryOnDisk( bool create_parents, std::string* ErrMsg ) { 524 // Get a writeable copy of the path name 525 std::string pathname(path); 526 527 // Null-terminate the last component 528 size_t lastchar = path.length() - 1 ; 529 530 if (pathname[lastchar] != '/') 531 ++lastchar; 532 533 pathname[lastchar] = '\0'; 534 535 if (createDirectoryHelper(&pathname[0], &pathname[lastchar], create_parents)) 536 return MakeErrMsg(ErrMsg, pathname + ": can't create directory"); 537 538 return false; 539} 540 541bool 542Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) { 543 // Make this into a unique file name 544 if (makeUnique( reuse_current, ErrMsg )) 545 return true; 546 547 // create the file 548 int fd = ::open(path.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0666); 549 if (fd < 0) 550 return MakeErrMsg(ErrMsg, path + ": can't create temporary file"); 551 ::close(fd); 552 return false; 553} 554 555bool 556Path::eraseFromDisk(bool remove_contents, std::string *ErrStr) const { 557 // Get the status so we can determine if it's a file or directory. 558 struct stat buf; 559 if (0 != stat(path.c_str(), &buf)) { 560 MakeErrMsg(ErrStr, path + ": can't get status of file"); 561 return true; 562 } 563 564 // Note: this check catches strange situations. In all cases, LLVM should 565 // only be involved in the creation and deletion of regular files. This 566 // check ensures that what we're trying to erase is a regular file. It 567 // effectively prevents LLVM from erasing things like /dev/null, any block 568 // special file, or other things that aren't "regular" files. 569 if (S_ISREG(buf.st_mode)) { 570 if (unlink(path.c_str()) != 0) 571 return MakeErrMsg(ErrStr, path + ": can't destroy file"); 572 return false; 573 } 574 575 if (!S_ISDIR(buf.st_mode)) { 576 if (ErrStr) *ErrStr = "not a file or directory"; 577 return true; 578 } 579 580 if (remove_contents) { 581 // Recursively descend the directory to remove its contents. 582 std::string cmd = "/bin/rm -rf " + path; 583 if (system(cmd.c_str()) != 0) { 584 MakeErrMsg(ErrStr, path + ": failed to recursively remove directory."); 585 return true; 586 } 587 return false; 588 } 589 590 // Otherwise, try to just remove the one directory. 591 std::string pathname(path); 592 size_t lastchar = path.length() - 1; 593 if (pathname[lastchar] == '/') 594 pathname[lastchar] = '\0'; 595 else 596 pathname[lastchar+1] = '\0'; 597 598 if (rmdir(pathname.c_str()) != 0) 599 return MakeErrMsg(ErrStr, pathname + ": can't erase directory"); 600 return false; 601} 602 603bool 604Path::renamePathOnDisk(const Path& newName, std::string* ErrMsg) { 605 if (0 != ::rename(path.c_str(), newName.c_str())) 606 return MakeErrMsg(ErrMsg, std::string("can't rename '") + path + "' as '" + 607 newName.str() + "'"); 608 return false; 609} 610 611bool 612Path::setStatusInfoOnDisk(const FileStatus &si, std::string *ErrStr) const { 613 struct utimbuf utb; 614 utb.actime = si.modTime.toPosixTime(); 615 utb.modtime = utb.actime; 616 if (0 != ::utime(path.c_str(),&utb)) 617 return MakeErrMsg(ErrStr, path + ": can't set file modification time"); 618 if (0 != ::chmod(path.c_str(),si.mode)) 619 return MakeErrMsg(ErrStr, path + ": can't set mode"); 620 return false; 621} 622 623bool 624Path::makeUnique(bool reuse_current, std::string* ErrMsg) { 625 bool Exists; 626 if (reuse_current && (fs::exists(path, Exists) || !Exists)) 627 return false; // File doesn't exist already, just use it! 628 629 // Append an XXXXXX pattern to the end of the file for use with mkstemp, 630 // mktemp or our own implementation. 631 // This uses std::vector instead of SmallVector to avoid a dependence on 632 // libSupport. And performance isn't critical here. 633 std::vector<char> Buf; 634 Buf.resize(path.size()+8); 635 char *FNBuffer = &Buf[0]; 636 path.copy(FNBuffer,path.size()); 637 bool isdir; 638 if (!fs::is_directory(path, isdir) && isdir) 639 strcpy(FNBuffer+path.size(), "/XXXXXX"); 640 else 641 strcpy(FNBuffer+path.size(), "-XXXXXX"); 642 643#if defined(HAVE_MKSTEMP) 644 int TempFD; 645 if ((TempFD = mkstemp(FNBuffer)) == -1) 646 return MakeErrMsg(ErrMsg, path + ": can't make unique filename"); 647 648 // We don't need to hold the temp file descriptor... we will trust that no one 649 // will overwrite/delete the file before we can open it again. 650 close(TempFD); 651 652 // Save the name 653 path = FNBuffer; 654 655 // By default mkstemp sets the mode to 0600, so update mode bits now. 656 AddPermissionBits (*this, 0666); 657#elif defined(HAVE_MKTEMP) 658 // If we don't have mkstemp, use the old and obsolete mktemp function. 659 if (mktemp(FNBuffer) == 0) 660 return MakeErrMsg(ErrMsg, path + ": can't make unique filename"); 661 662 // Save the name 663 path = FNBuffer; 664#else 665 // Okay, looks like we have to do it all by our lonesome. 666 static unsigned FCounter = 0; 667 // Try to initialize with unique value. 668 if (FCounter == 0) FCounter = ((unsigned)getpid() & 0xFFFF) << 8; 669 char* pos = strstr(FNBuffer, "XXXXXX"); 670 do { 671 if (++FCounter > 0xFFFFFF) { 672 return MakeErrMsg(ErrMsg, 673 path + ": can't make unique filename: too many files"); 674 } 675 sprintf(pos, "%06X", FCounter); 676 path = FNBuffer; 677 } while (exists()); 678 // POSSIBLE SECURITY BUG: An attacker can easily guess the name and exploit 679 // LLVM. 680#endif 681 return false; 682} 683} // end llvm namespace 684