38#include <mach-o/dyld.h>
40#if __has_include(<sys/clonefile.h>)
41#include <sys/clonefile.h>
43#elif defined(__FreeBSD__)
45#if __FreeBSD_version >= 1300057
48#include <machine/elf.h>
51#elif defined(__DragonFly__)
69#define PATH_MAX _XOPEN_PATH_MAX
74#if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && \
75 !defined(__linux__) && !defined(__FreeBSD_kernel__) && !defined(_AIX) && \
76 !defined(__managarm__)
77#include <sys/statvfs.h>
78#define STATVFS statvfs
79#define FSTATVFS fstatvfs
80#define STATVFS_F_FRSIZE(vfs) vfs.f_frsize
82#if defined(__OpenBSD__) || defined(__FreeBSD__)
85#elif defined(__linux__) || defined(__managarm__)
88#include <sys/statfs.h>
94#include <sys/vmount.h>
99#define FSTATVFS fstatfs
100#define STATVFS_F_FRSIZE(vfs) static_cast<uint64_t>(vfs.f_bsize)
103#if defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__) || \
105#define STATVFS_F_FLAG(vfs) (vfs).f_flag
107#define STATVFS_F_FLAG(vfs) (vfs).f_flags
116#if defined(__FreeBSD__) || defined(__NetBSD__) || \
117 (defined(__OpenBSD__) && !defined(HAVE_GETEXECPATH)) || \
118 defined(__FreeBSD_kernel__) || defined(__linux__) || \
119 defined(__CYGWIN__) || defined(__DragonFly__) || defined(_AIX) || \
120 defined(__GNU__) || \
121 (defined(__sun__) && defined(__svr4__) || defined(__HAIKU__)) || \
122 defined(__managarm__)
123static int test_dir(
char ret[
PATH_MAX],
const char *dir,
const char *bin) {
127 int chars = snprintf(fullpath,
PATH_MAX,
"%s/%s", dir, bin);
132 if (!realpath(fullpath, ret))
134 if (stat(fullpath, &sb) != 0)
140static char *getprogpath(
char ret[
PATH_MAX],
const char *bin) {
146 if (test_dir(ret,
"/", bin) == 0)
152 if (strchr(bin,
'/')) {
156 if (test_dir(ret, cwd, bin) == 0)
163 if ((pv = getenv(
"PATH")) ==
nullptr)
165 char *s = strdup(pv);
169 for (
char *t = strtok_r(s,
":", &state); t !=
nullptr;
170 t = strtok_r(
nullptr,
":", &state)) {
171 if (test_dir(ret, t, bin) == 0) {
186#if defined(__APPLE__)
191 uint32_t
size =
sizeof(exe_path);
192 if (_NSGetExecutablePath(exe_path, &
size) == 0) {
194 if (realpath(exe_path, link_path))
197#elif defined(__FreeBSD__)
203#if __FreeBSD_version >= 1300057
204 if (elf_aux_info(AT_EXECPATH, exe_path,
sizeof(exe_path)) == 0) {
206 if (realpath(exe_path, link_path))
213 char **
p = ::environ;
217 for (Elf_Auxinfo *aux = (Elf_Auxinfo *)p; aux->a_type != AT_NULL; aux++) {
218 if (aux->a_type == AT_EXECPATH) {
220 if (realpath((
char *)aux->a_un.a_ptr, link_path))
226 if (getprogpath(exe_path, argv0) != NULL)
228#elif defined(_AIX) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) || \
230 const char *curproc =
"/proc/curproc/file";
233 ssize_t len =
::readlink(curproc, exe_path,
sizeof(exe_path));
237 len = std::min(len, ssize_t(
sizeof(exe_path) - 1));
238 exe_path[len] =
'\0';
243 if (getprogpath(exe_path, argv0) != NULL)
245#elif defined(__linux__) || defined(__CYGWIN__) || defined(__gnu_hurd__) || \
246 defined(__managarm__)
248 const char *aPath =
"/proc/self/exe";
251 ssize_t len =
::readlink(aPath, exe_path,
sizeof(exe_path));
257 len = std::min(len, ssize_t(
sizeof(exe_path) - 1));
258 exe_path[len] =
'\0';
264#if _POSIX_VERSION >= 200112 || defined(__GLIBC__)
265 if (
char *
real_path = realpath(exe_path,
nullptr)) {
266 std::string ret = std::string(
real_path);
277 if (getprogpath(exe_path, argv0))
279#elif defined(__OpenBSD__)
281#ifdef HAVE_GETEXECPATH
282 if (getexecpath(exe_path,
sizeof(exe_path)) == 0)
285 if (getprogpath(exe_path, argv0) != NULL)
288#elif defined(__HAIKU__)
291 if (getprogpath(exe_path, argv0) != NULL)
293#elif defined(__sun__) && defined(__svr4__)
295 const char *aPath =
"/proc/self/execname";
297 int fd = open(aPath, O_RDONLY);
300 if (
read(fd, exe_path,
sizeof(exe_path)) < 0)
305 if (getprogpath(exe_path, argv0) != NULL)
307#elif defined(__MVS__)
310 char exe_path[PS_PATHBLEN];
311 pid_t pid = getpid();
313 memset(&buf, 0,
sizeof(buf));
314 buf.ps_pathptr = exe_path;
315 buf.ps_pathlen =
sizeof(exe_path);
318 if ((token = w_getpsent(token, &buf,
sizeof(buf))) <= 0)
320 if (buf.ps_pid != pid)
327#elif defined(HAVE_DLOPEN)
330 int err = dladdr(MainAddr, &DLInfo);
337 if (realpath(DLInfo.dli_fname, link_path))
340#error GetMainExecutable is not implemented on this host yet.
354 return UniqueID(fs_st_dev, fs_st_ino);
359ErrorOr<space_info>
disk_space(
const Twine &Path) {
361 if (::STATVFS(
const_cast<char *
>(
Path.str().c_str()), &Vfs))
363 auto FrSize = STATVFS_F_FRSIZE(Vfs);
366 SpaceInfo.free =
static_cast<uint64_t>(Vfs.f_bfree) * FrSize;
367 SpaceInfo.available =
static_cast<uint64_t>(Vfs.f_bavail) * FrSize;
371std::error_code
current_path(SmallVectorImpl<char> &result) {
376 const char *pwd = ::getenv(
"PWD");
377 llvm::sys::fs::file_status PWDStatus, DotStatus;
382 result.
append(pwd, pwd + strlen(pwd));
383 return std::error_code();
389 if (::getcwd(result.
data(), result.
size()) ==
nullptr) {
391 if (errno != ENOMEM) {
403 return std::error_code();
409 SmallString<128> path_storage;
412 if (::chdir(
p.begin()) == -1)
415 return std::error_code();
420 SmallString<128> path_storage;
423 if (::mkdir(
p.begin(), Perms) == -1) {
424 if (errno != EEXIST || !IgnoreExisting)
428 return std::error_code();
431std::error_code
create_symlink(
const Twine &to,
const Twine &from) {
433 SmallString<128> from_storage;
434 SmallString<128> to_storage;
438 if (::symlink(t.
begin(),
f.begin()) == -1)
441 return std::error_code();
444std::error_code
create_link(
const Twine &to,
const Twine &from) {
453 SmallString<128> from_storage;
454 SmallString<128> to_storage;
458 if (::link(t.
begin(),
f.begin()) == -1)
461 return std::error_code();
464std::error_code
remove(
const Twine &path,
bool IgnoreNonExisting) {
465 SmallString<128> path_storage;
466 StringRef
p = path.toNullTerminatedStringRef(path_storage);
469 if (lstat(
p.begin(), &buf) != 0) {
470 if (errno != ENOENT || !IgnoreNonExisting)
472 return std::error_code();
480 if (!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode) && !S_ISLNK(buf.st_mode))
484 if (errno != ENOENT || !IgnoreNonExisting)
488 return std::error_code();
491static bool is_local_impl(
struct STATVFS &Vfs) {
492#if defined(__linux__) || defined(__GNU__) || defined(__managarm__)
493#ifndef NFS_SUPER_MAGIC
494#define NFS_SUPER_MAGIC 0x6969
496#ifndef SMB_SUPER_MAGIC
497#define SMB_SUPER_MAGIC 0x517B
499#ifndef CIFS_MAGIC_NUMBER
500#define CIFS_MAGIC_NUMBER 0xFF534D42
502#if defined(__GNU__) && ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 39)))
503 switch ((uint32_t)Vfs.__f_type) {
505 switch ((uint32_t)Vfs.f_type) {
507 case NFS_SUPER_MAGIC:
508 case SMB_SUPER_MAGIC:
509 case CIFS_MAGIC_NUMBER:
514#elif defined(__CYGWIN__)
517#elif defined(__Fuchsia__)
520#elif defined(__EMSCRIPTEN__)
523#elif defined(__HAIKU__)
529 StringRef fstype(Vfs.f_basetype);
531 return fstype !=
"nfs";
536 size_t BufSize = 2048
u;
537 std::unique_ptr<char[]> Buf;
540 Buf = std::make_unique<char[]>(BufSize);
541 Ret = mntctl(MCTL_QUERY, BufSize, Buf.get());
544 BufSize = *
reinterpret_cast<unsigned int *
>(Buf.get());
553 char *CurObjPtr = Buf.get();
555 struct vmount *Vp =
reinterpret_cast<struct vmount *
>(CurObjPtr);
556 static_assert(
sizeof(Vfs.f_fsid) ==
sizeof(Vp->vmt_fsid),
557 "fsid length mismatch");
558 if (memcmp(&Vfs.f_fsid, &Vp->vmt_fsid,
sizeof Vfs.f_fsid) == 0)
559 return (Vp->vmt_flags & MNT_REMOTE) == 0;
561 CurObjPtr += Vp->vmt_length;
566#elif defined(__MVS__)
571 return !!(STATVFS_F_FLAG(Vfs) & MNT_LOCAL);
575std::error_code
is_local(
const Twine &Path,
bool &Result) {
579 if (::STATVFS(
const_cast<char *
>(
Path.str().c_str()), &Vfs))
582 Result = is_local_impl(Vfs);
583 return std::error_code();
586std::error_code
is_local(
int FD,
bool &Result) {
590 if (::FSTATVFS(FD, &Vfs))
593 Result = is_local_impl(Vfs);
594 return std::error_code();
597std::error_code
rename(
const Twine &from,
const Twine &to) {
599 SmallString<128> from_storage;
600 SmallString<128> to_storage;
607 return std::error_code();
616 return std::error_code();
639 SmallString<128> PathStorage;
640 StringRef
P =
Path.toNullTerminatedStringRef(PathStorage);
648 if (0 != stat(
P.begin(), &buf))
650 if (!S_ISREG(buf.st_mode))
654 return std::error_code();
665 return A.fs_st_dev ==
B.fs_st_dev &&
A.fs_st_ino ==
B.fs_st_ino;
668std::error_code
equivalent(
const Twine &
A,
const Twine &
B,
bool &result) {
672 if (std::error_code ec =
status(
A, fsA))
674 if (std::error_code ec =
status(
B, fsB))
677 return std::error_code();
680static void expandTildeExpr(SmallVectorImpl<char> &Path) {
681 StringRef PathStr(
Path.begin(),
Path.size());
682 if (PathStr.empty() || !PathStr.starts_with(
"~"))
685 PathStr = PathStr.drop_front();
688 StringRef Remainder = PathStr.substr(Expr.
size() + 1);
689 SmallString<128> Storage;
698 Path[0] = Storage[0];
705 std::unique_ptr<char[]> Buf;
706 long BufSize = sysconf(_SC_GETPW_R_SIZE_MAX);
709 Buf = std::make_unique<char[]>(BufSize);
712 struct passwd *
Entry =
nullptr;
713 getpwnam_r(
User.c_str(), &Pwd, Buf.get(), BufSize, &Entry);
715 if (!Entry || !
Entry->pw_dir) {
726void expand_tilde(
const Twine &path, SmallVectorImpl<char> &dest) {
732 expandTildeExpr(dest);
738 else if (S_ISREG(
Mode))
740 else if (S_ISBLK(
Mode))
742 else if (S_ISCHR(
Mode))
744 else if (S_ISFIFO(
Mode))
746 else if (S_ISSOCK(
Mode))
748 else if (S_ISLNK(
Mode))
753static std::error_code fillStatus(
int StatRet,
const struct stat &Status,
764 uint32_t atime_nsec, mtime_nsec;
765#if defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
766 atime_nsec = Status.st_atimespec.tv_nsec;
767 mtime_nsec = Status.st_mtimespec.tv_nsec;
768#elif defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
769 atime_nsec = Status.st_atim.tv_nsec;
770 mtime_nsec = Status.st_mtim.tv_nsec;
772 atime_nsec = mtime_nsec = 0;
777 Status.st_nlink, Status.st_ino, Status.st_atime,
778 atime_nsec, Status.st_mtime, mtime_nsec, Status.st_uid,
779 Status.st_gid, Status.st_size);
781 return std::error_code();
787 SmallString<128> PathStorage;
788 StringRef
P =
Path.toNullTerminatedStringRef(PathStorage);
791 int StatRet = (Follow ? ::stat : ::lstat)(
P.begin(), &Status);
792 return fillStatus(StatRet, Status, Result);
796 return status(
F.get(), Result);
803 int StatRet = ::fstat(FD, &Status);
804 return fillStatus(StatRet, Status, Result);
810 unsigned Mask = ::umask(0);
816 SmallString<128> PathStorage;
817 StringRef
P =
Path.toNullTerminatedStringRef(PathStorage);
819 if (::chmod(
P.begin(), Permissions))
821 return std::error_code();
825 if (::fchmod(FD, Permissions))
827 return std::error_code();
832#if defined(HAVE_FUTIMENS)
836 if (::futimens(FD, Times))
838 return std::error_code();
839#elif defined(HAVE_FUTIMES)
842 std::chrono::time_point_cast<std::chrono::microseconds>(AccessTime));
844 sys::toTimeVal(std::chrono::time_point_cast<std::chrono::microseconds>(
846 if (::futimes(FD, Times))
848 return std::error_code();
849#elif defined(__MVS__)
851 memset(&Attr, 0,
sizeof(Attr));
852 Attr.att_atimechg = 1;
854 Attr.att_mtimechg = 1;
856 if (::__fchattr(FD, &Attr,
sizeof(Attr)) != 0)
858 return std::error_code();
860#warning Missing futimes() and futimens()
866 mapmode
Mode,
const char *Name) {
869 int flags = (Mode ==
readwrite) ? MAP_SHARED : MAP_PRIVATE;
870 int prot = (Mode ==
readonly) ? PROT_READ : (PROT_READ | PROT_WRITE);
871#if defined(MAP_NORESERVE)
872 flags |= MAP_NORESERVE;
874#if defined(__APPLE__)
885#if defined(MAP_RESILIENT_CODESIGN)
886 flags |= MAP_RESILIENT_CODESIGN;
888#if defined(MAP_RESILIENT_MEDIA)
889 flags |= MAP_RESILIENT_MEDIA;
894 Mapping = ::mmap(
nullptr, Size, prot, flags, FD.
get(),
Offset);
895 if (Mapping == MAP_FAILED)
897 return std::error_code();
901 uint64_t offset, std::error_code &ec,
909 copyFrom(mapped_file_region());
912void mapped_file_region::unmapImpl() {
914 ::munmap(Mapping,
Size);
917std::error_code mapped_file_region::sync()
const {
919 return std::error_code(Res, std::generic_category());
920 return std::error_code();
923void mapped_file_region::dontNeedImpl() {
927#if defined(__MVS__) || defined(_AIX)
929#elif defined(POSIX_MADV_DONTNEED)
930 ::posix_madvise(Mapping,
Size, POSIX_MADV_DONTNEED);
932 ::madvise(Mapping,
Size, MADV_DONTNEED);
936void mapped_file_region::willNeedImpl() {
940#if defined(__MVS__) || defined(_AIX)
942#elif defined(POSIX_MADV_WILLNEED)
943 ::posix_madvise(Mapping,
Size, POSIX_MADV_WILLNEED);
945 ::madvise(Mapping,
Size, MADV_WILLNEED);
949void mapped_file_region::randomAccessImpl() {
953#if defined(__MVS__) || defined(_AIX)
955#elif defined(POSIX_MADV_RANDOM)
956 ::posix_madvise(Mapping,
Size, POSIX_MADV_RANDOM);
958 ::madvise(Mapping,
Size, MADV_RANDOM);
964std::error_code detail::directory_iterator_construct(detail::DirIterState &it,
966 bool follow_symlinks) {
970 DIR *directory = ::opendir(path_null.c_str());
974 it.IterationHandle =
reinterpret_cast<intptr_t
>(directory);
977 it.CurrentEntry = directory_entry(path_null.str(), follow_symlinks);
981std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) {
982 if (it.IterationHandle)
983 ::closedir(
reinterpret_cast<DIR *
>(it.IterationHandle));
984 it.IterationHandle = 0;
985 it.CurrentEntry = directory_entry();
986 return std::error_code();
989static file_type direntType(dirent *Entry) {
996 return typeForMode(DTTOIF(Entry->d_type));
999 return file_type::type_unknown;
1003std::error_code detail::directory_iterator_increment(detail::DirIterState &It) {
1007 dirent *CurDir = ::readdir(
reinterpret_cast<DIR *
>(It.IterationHandle));
1008 if (CurDir ==
nullptr && errno != 0) {
1010 }
else if (CurDir !=
nullptr) {
1012 if ((
Name.size() == 1 && Name[0] ==
'.') ||
1013 (
Name.size() == 2 && Name[0] ==
'.' && Name[1] ==
'.'))
1015 It.CurrentEntry.replace_filename(Name, direntType(CurDir));
1020 return std::error_code();
1027 if (
auto EC =
fs::status(Path, s, FollowSymlinks))
1034#if defined(__linux__)
1035#define TRY_PROC_SELF_FD
1038#if !defined(F_GETPATH) && defined(TRY_PROC_SELF_FD)
1039static bool hasProcSelfFD() {
1042 static const bool Result = (::access(
"/proc/self/fd", R_OK) == 0);
1047static int nativeOpenFlags(CreationDisposition Disp, OpenFlags Flags,
1052 else if (
Access == FA_Write)
1054 else if (
Access == (FA_Read | FA_Write))
1059 if (Flags & OF_Append)
1062 if (Disp == CD_CreateNew) {
1065 }
else if (Disp == CD_CreateAlways) {
1068 }
else if (Disp == CD_OpenAlways) {
1070 }
else if (Disp == CD_OpenExisting) {
1078 if (Flags & OF_Append)
1083 if (!(Flags & OF_ChildInherit))
1091 CreationDisposition Disp, FileAccess
Access,
1092 OpenFlags Flags,
unsigned Mode) {
1101 auto Open = [&]() { return ::open(
P.begin(), OpenFlags,
Mode); };
1105 if (!(Flags & OF_ChildInherit)) {
1106 int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
1108 assert(r == 0 &&
"fcntl(F_SETFD, FD_CLOEXEC) failed");
1166 if ((Flags & OF_Append) && lseek(ResultFD, 0, SEEK_END) == -1)
1169 if (fstat(ResultFD, &Stat) == -1)
1171 if (S_ISREG(Stat.st_mode)) {
1172 bool DoSetTag = (
Access &
FA_Write) && (Disp != CD_OpenExisting) &&
1173 !Stat.st_tag.ft_txtflag && !Stat.st_tag.ft_ccsid &&
1175 if (Flags & OF_Text) {
1176 if ((
Access & FA_Write) && (Disp != CD_OpenExisting)) {
1178 if (Stat.st_tag.ft_txtflag && Stat.st_tag.ft_ccsid != FT_UNTAGGED)
1179 ccsid = Stat.st_tag.ft_ccsid;
1180 if (
auto EC = llvm::enableAutoConversion(ResultFD, ccsid))
1183 if (
auto EC = llvm::setzOSFileTag(ResultFD, ccsid,
true))
1186 }
else if (
auto EC = llvm::enableAutoConversion(ResultFD))
1189 if (
auto EC = llvm::disableAutoConversion(ResultFD))
1193 llvm::setzOSFileTag(ResultFD, FT_BINARY,
false))
1200 return std::error_code();
1204 FileAccess
Access, OpenFlags Flags,
1220 std::error_code
EC =
1221 openFile(Name, ResultFD, CD_OpenExisting, FA_Read, Flags, 0666);
1227 return std::error_code();
1229#if defined(F_GETPATH)
1233 if (::fcntl(ResultFD, F_GETPATH, Buffer) != -1)
1234 RealPath->
append(Buffer, Buffer + strlen(Buffer));
1237#if defined(TRY_PROC_SELF_FD)
1238 if (hasProcSelfFD()) {
1240 snprintf(ProcPath,
sizeof(ProcPath),
"/proc/self/fd/%d", ResultFD);
1241 ssize_t CharCount = ::readlink(ProcPath, Buffer,
sizeof(Buffer));
1243 RealPath->
append(Buffer, Buffer + CharCount);
1250 if (::realpath(
P.begin(), Buffer) !=
nullptr)
1251 RealPath->
append(Buffer, Buffer + strlen(Buffer));
1252#if defined(TRY_PROC_SELF_FD)
1256 return std::error_code();
1269#if defined(__MVS__) || defined(_AIX)
1271 if (fstat(ResultFD, &
Status) == -1)
1273 if (S_ISDIR(
Status.st_mode))
1286#if defined(__APPLE__)
1287 size_t Size = std::min<size_t>(Buf.
size(), INT32_MAX);
1302#if defined(__APPLE__)
1303 size_t Size = std::min<size_t>(Buf.
size(), INT32_MAX);
1311 if (lseek(FD.
get(),
Offset, SEEK_SET) == -1)
1323 auto Start = std::chrono::steady_clock::now();
1327 memset(&Lock, 0,
sizeof(Lock));
1329 case LockKind::Exclusive:
1330 Lock.l_type = F_WRLCK;
1332 case LockKind::Shared:
1333 Lock.l_type = F_RDLCK;
1336 Lock.l_whence = SEEK_SET;
1339 if (::fcntl(FD, F_SETLK, &Lock) != -1)
1340 return std::error_code();
1342 if (Error != EACCES && Error != EAGAIN)
1343 return std::error_code(Error, std::generic_category());
1347 }
while (std::chrono::steady_clock::now() < End);
1351std::error_code
lockFile(
int FD, LockKind Kind) {
1353 memset(&Lock, 0,
sizeof(Lock));
1355 case LockKind::Exclusive:
1356 Lock.l_type = F_WRLCK;
1358 case LockKind::Shared:
1359 Lock.l_type = F_RDLCK;
1362 Lock.l_whence = SEEK_SET;
1366 return std::error_code();
1372 Lock.l_type = F_UNLCK;
1373 Lock.l_whence = SEEK_SET;
1377 return std::error_code();
1389template <
typename T>
1390static std::error_code remove_directories_impl(
const T &Entry,
1391 bool IgnoreErrors) {
1393 directory_iterator Begin(Entry, EC,
false);
1394 directory_iterator End;
1395 while (Begin != End) {
1396 auto &Item = *Begin;
1400 EC = remove_directories_impl(Item, IgnoreErrors);
1401 if (EC && !IgnoreErrors)
1406 if (EC && !IgnoreErrors)
1408 }
else if (!IgnoreErrors) {
1412 Begin.increment(EC);
1413 if (EC && !IgnoreErrors)
1416 return std::error_code();
1420 auto EC = remove_directories_impl(
path, IgnoreErrors);
1421 if (EC && !IgnoreErrors)
1424 if (EC && !IgnoreErrors)
1426 return std::error_code();
1430 bool expand_tilde) {
1434 if (
path.isTriviallyEmpty())
1435 return std::error_code();
1439 path.toVector(Storage);
1440 expandTildeExpr(Storage);
1447 if (::realpath(
P.begin(), Buffer) ==
nullptr)
1449 dest.
append(Buffer, Buffer + strlen(Buffer));
1450 return std::error_code();
1468 size_t BufSize = std::max(std::size_t{32}, dest.
capacity());
1471 ssize_t
Len = ::readlink(
P.begin(), dest.
data(), dest.
size());
1474 if (
static_cast<size_t>(Len) < BufSize) {
1476 return std::error_code();
1484 auto FChown = [&]() { return ::fchown(FD,
Owner, Group); };
1488 return std::error_code();
1496 std::unique_ptr<char[]> Buf;
1497 char *RequestedDir = getenv(
"HOME");
1498 if (!RequestedDir) {
1499 long BufSize = sysconf(_SC_GETPW_R_SIZE_MAX);
1502 Buf = std::make_unique<char[]>(BufSize);
1504 struct passwd *pw =
nullptr;
1505 getpwuid_r(getuid(), &Pwd, Buf.get(), BufSize, &pw);
1506 if (pw && pw->pw_dir)
1507 RequestedDir = pw->pw_dir;
1513 result.
append(RequestedDir, RequestedDir + strlen(RequestedDir));
1517static bool getDarwinConfDir(
bool TempDir, SmallVectorImpl<char> &Result) {
1518#if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR)
1521 int ConfName = TempDir ? _CS_DARWIN_USER_TEMP_DIR : _CS_DARWIN_USER_CACHE_DIR;
1522 size_t ConfLen = confstr(ConfName,
nullptr, 0);
1526 ConfLen = confstr(ConfName,
Result.data(),
Result.size());
1527 }
while (ConfLen > 0 && ConfLen !=
Result.size());
1545 append(result,
"Library",
"Preferences");
1551 if (
const char *RequestedDir = getenv(
"XDG_CONFIG_HOME")) {
1553 result.
append(RequestedDir, RequestedDir + strlen(RequestedDir));
1561 append(result,
".config");
1567 if (getDarwinConfDir(
false , result)) {
1573 if (
const char *RequestedDir = getenv(
"XDG_CACHE_HOME")) {
1575 result.
append(RequestedDir, RequestedDir + strlen(RequestedDir));
1582 append(result,
".cache");
1586static const char *getEnvTempDir() {
1589 const char *EnvironmentVariables[] = {
"TMPDIR",
"TMP",
"TEMP",
"TEMPDIR"};
1590 for (
const char *Env : EnvironmentVariables) {
1591 if (
const char *Dir = std::getenv(Env))
1598static const char *getDefaultTempDir(
bool ErasedOnReboot) {
1612 if (ErasedOnReboot) {
1614 if (
const char *RequestedDir = getEnvTempDir()) {
1615 Result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
1620 if (getDarwinConfDir(ErasedOnReboot, Result))
1623 const char *RequestedDir = getDefaultTempDir(ErasedOnReboot);
1624 Result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
1637std::error_code
copy_file(
const Twine &From,
const Twine &To) {
1638 std::string FromS = From.
str();
1639 std::string ToS = To.
str();
1640#if __has_builtin(__builtin_available)
1641 if (__builtin_available(macos 10.12, *)) {
1648 if (!clonefile(FromS.c_str(), ToS.c_str(), 0))
1649 return std::error_code();
1659 return std::error_code(Errno, std::generic_category());
1668 if (!copyfile(FromS.c_str(), ToS.c_str(), NULL, COPYFILE_DATA))
1669 return std::error_code();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static ManagedStatic< DebugCounterOwner > Owner
amode Optimize addressing mode
std::unique_ptr< MemoryBuffer > openFile(const Twine &Path)
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Represents the result of a call to sys::fs::status().
size_t size() const
Get the array size.
Represents either an error or a value T.
std::error_code getError() const
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void resize_for_overwrite(size_type N)
Like resize, but T is POD, the new values won't be initialized.
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void truncate(size_type N)
Like resize, but requires that N is less than size().
pointer data()
Return a pointer to the vector's buffer, even if empty().
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
constexpr bool empty() const
Check if the string is empty.
constexpr size_t size() const
Get the string size.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
LLVM_ABI StringRef toNullTerminatedStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single null terminated StringRef if it can be represented as such.
bool isTriviallyEmpty() const
Check if this twine is trivially empty; a false return value does not necessarily mean the twine is e...
LLVM_ABI void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
static LLVM_ABI std::error_code SafelyCloseFileDescriptor(int FD)
static unsigned getPageSizeEstimate()
Get the process's estimated page size.
uint32_t fs_st_mtime_nsec
uint32_t fs_st_atime_nsec
LLVM_ABI TimePoint getLastModificationTime() const
The file modification time as reported from the underlying file system.
LLVM_ABI TimePoint getLastAccessedTime() const
The file access time as reported from the underlying file system.
Represents the result of a call to sys::fs::status().
LLVM_ABI uint32_t getLinkCount() const
LLVM_ABI UniqueID getUniqueID() const
mapped_file_region()=default
@ readonly
May only access map via const_data as read only.
@ readwrite
May access map via data and modify it. Written to path.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
LLVM_ABI std::error_code directory_iterator_destruct(DirIterState &)
LLVM_ABI std::error_code directory_iterator_increment(DirIterState &)
LLVM_ABI std::error_code readlink(const Twine &path, SmallVectorImpl< char > &output)
Read the target of a symbolic link.
LLVM_ABI bool can_execute(const Twine &Path)
Can we execute this file?
LLVM_ABI std::error_code closeFile(file_t &F)
Close the file object.
LLVM_ABI std::error_code rename(const Twine &from, const Twine &to)
Rename from to to.
LLVM_ABI std::error_code create_hard_link(const Twine &to, const Twine &from)
Create a hard link from from to to, or return an error.
LLVM_ABI std::error_code access(const Twine &Path, AccessMode Mode)
Can the file be accessed?
LLVM_ABI ErrorOr< space_info > disk_space(const Twine &Path)
Get disk space usage information.
LLVM_ABI Expected< size_t > readNativeFile(file_t FileHandle, MutableArrayRef< char > Buf)
Reads Buf.size() bytes from FileHandle into Buf.
LLVM_ABI unsigned getUmask()
Get file creation mode mask of the process.
LLVM_ABI bool exists(const basic_file_status &status)
Does file exist?
LLVM_ABI Expected< file_t > openNativeFile(const Twine &Name, CreationDisposition Disp, FileAccess Access, OpenFlags Flags, unsigned Mode=0666)
Opens a file with the specified creation disposition, access mode, and flags and returns a platform-s...
LLVM_ABI file_t getStdoutHandle()
Return an open handle to standard out.
file_type
An enumeration for the file system's view of the type.
LLVM_ABI std::error_code create_link(const Twine &to, const Twine &from)
Create a link from from to to.
LLVM_ABI std::error_code create_symlink(const Twine &to, const Twine &from)
Create a symbolic link from from to to.
LLVM_ABI void expand_tilde(const Twine &path, SmallVectorImpl< char > &output)
Expands ~ expressions to the user's home directory.
LLVM_ABI std::error_code lockFile(int FD, LockKind Kind=LockKind::Exclusive)
Lock the file.
LLVM_ABI std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
LLVM_ABI std::error_code set_current_path(const Twine &path)
Set the current path.
LLVM_ABI std::error_code real_path(const Twine &path, SmallVectorImpl< char > &output, bool expand_tilde=false)
Collapse all .
@ CD_OpenAlways
CD_OpenAlways - When opening a file:
LLVM_ABI Expected< size_t > readNativeFileSlice(file_t FileHandle, MutableArrayRef< char > Buf, uint64_t Offset)
Reads Buf.size() bytes from FileHandle at offset Offset into Buf.
LLVM_ABI std::error_code changeFileOwnership(int FD, uint32_t Owner, uint32_t Group)
Change ownership of a file.
LLVM_ABI std::string getMainExecutable(const char *argv0, void *MainExecAddr)
Return the path to the main executable, given the value of argv[0] from program startup and the addre...
LLVM_ABI Expected< file_t > openNativeFileForRead(const Twine &Name, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
LLVM_ABI bool status_known(const basic_file_status &s)
Is status available?
LLVM_ABI std::error_code resize_file_sparse(int FD, uint64_t Size)
Resize path to size with sparse files explicitly enabled.
LLVM_ABI std::error_code copy_file(const Twine &From, const Twine &To)
Copy the contents of From to To.
LLVM_ABI std::error_code tryLockFile(int FD, std::chrono::milliseconds Timeout=std::chrono::milliseconds(0), LockKind Kind=LockKind::Exclusive)
Try to locks the file during the specified time.
LLVM_ABI std::error_code current_path(SmallVectorImpl< char > &result)
Get the current path.
LLVM_ABI std::error_code resize_file(int FD, uint64_t Size)
Resize path to size.
LLVM_ABI std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
LLVM_ABI std::error_code create_directory(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create the directory in path.
LLVM_ABI std::error_code is_local(const Twine &path, bool &result)
Is the file mounted on a local filesystem?
LLVM_ABI std::error_code openFileForRead(const Twine &Name, int &ResultFD, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
LLVM_ABI std::error_code remove_directories(const Twine &path, bool IgnoreErrors=true)
Recursively delete a directory.
LLVM_ABI bool equivalent(file_status A, file_status B)
Do file_status's represent the same thing?
LLVM_ABI file_t getStderrHandle()
Return an open handle to standard error.
LLVM_ABI std::error_code setLastAccessAndModificationTime(int FD, TimePoint<> AccessTime, TimePoint<> ModificationTime)
Set the file modification and access time.
LLVM_ABI file_t getStdinHandle()
Return an open handle to standard in.
LLVM_ABI std::error_code unlockFile(int FD)
Unlock the file.
LLVM_ABI std::error_code setPermissions(const Twine &Path, perms Permissions)
Set file permissions.
LLVM_ABI bool is_directory(const basic_file_status &status)
Does status represent a directory?
LLVM_ABI bool cache_directory(SmallVectorImpl< char > &result)
Get the directory where installed packages should put their machine-local cache, e....
LLVM_ABI bool user_config_directory(SmallVectorImpl< char > &result)
Get the directory where packages should read user-specific configurations.
LLVM_ABI void system_temp_directory(bool erasedOnReboot, SmallVectorImpl< char > &result)
Get the typical temporary directory for the system, e.g., "/var/tmp" or "C:/TEMP".
LLVM_ABI bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
LLVM_ABI bool home_directory(SmallVectorImpl< char > &result)
Get the user's home directory.
LLVM_ABI bool is_separator(char value, Style style=Style::native)
Check whether the given char is a path separator on the host OS.
void violationIfEnabled()
ScopedSetting scopedDisable()
decltype(auto) RetryAfterSignal(const FailT &Fail, const Fun &F, const Args &... As)
std::chrono::time_point< std::chrono::system_clock, D > TimePoint
A time point on the system clock.
TimePoint< std::chrono::seconds > toTimePoint(std::time_t T)
Convert a std::time_t to a TimePoint.
struct timespec toTimeSpec(TimePoint<> TP)
Convert a time point to struct timespec.
struct timeval toTimeVal(TimePoint< std::chrono::microseconds > TP)
Convert a time point to struct timeval.
std::time_t toTimeT(TimePoint<> TP)
Convert a TimePoint to std::time_t.
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
std::error_code make_error_code(BitcodeError E)
@ no_such_file_or_directory
@ operation_not_permitted
@ Timeout
Reached timeout while waiting for the owner to release the lock.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
std::error_code errnoAsErrorCode()
Helper to get errno as an std::error_code.
This class wraps the platform specific file handle/descriptor type to provide an unified representati...
static constexpr value_type Invalid
Value for an invalid file descriptor.
value_type get() const
Get the underlying value and return a platform specific value.
This class wraps the platform specific file handle/descriptor type to provide an unified representati...
space_info - Self explanatory.