Path.inc 37 KB

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