xref: /aosp_15_r20/external/llvm/lib/Support/Unix/Path.inc (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker//===- llvm/Support/Unix/Path.inc - Unix Path Implementation ----*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker//
3*9880d681SAndroid Build Coastguard Worker//                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker//
5*9880d681SAndroid Build Coastguard Worker// This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker// License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker//
8*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker//
10*9880d681SAndroid Build Coastguard Worker// This file implements the Unix specific implementation of the Path API.
11*9880d681SAndroid Build Coastguard Worker//
12*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker//=== WARNING: Implementation here must contain only generic UNIX code that
16*9880d681SAndroid Build Coastguard Worker//===          is guaranteed to work on *all* UNIX variants.
17*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker#include "Unix.h"
20*9880d681SAndroid Build Coastguard Worker#include <limits.h>
21*9880d681SAndroid Build Coastguard Worker#include <stdio.h>
22*9880d681SAndroid Build Coastguard Worker#if HAVE_SYS_STAT_H
23*9880d681SAndroid Build Coastguard Worker#include <sys/stat.h>
24*9880d681SAndroid Build Coastguard Worker#endif
25*9880d681SAndroid Build Coastguard Worker#if HAVE_FCNTL_H
26*9880d681SAndroid Build Coastguard Worker#include <fcntl.h>
27*9880d681SAndroid Build Coastguard Worker#endif
28*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_UNISTD_H
29*9880d681SAndroid Build Coastguard Worker#include <unistd.h>
30*9880d681SAndroid Build Coastguard Worker#endif
31*9880d681SAndroid Build Coastguard Worker#ifdef HAVE_SYS_MMAN_H
32*9880d681SAndroid Build Coastguard Worker#include <sys/mman.h>
33*9880d681SAndroid Build Coastguard Worker#endif
34*9880d681SAndroid Build Coastguard Worker#if HAVE_DIRENT_H
35*9880d681SAndroid Build Coastguard Worker# include <dirent.h>
36*9880d681SAndroid Build Coastguard Worker# define NAMLEN(dirent) strlen((dirent)->d_name)
37*9880d681SAndroid Build Coastguard Worker#else
38*9880d681SAndroid Build Coastguard Worker# define dirent direct
39*9880d681SAndroid Build Coastguard Worker# define NAMLEN(dirent) (dirent)->d_namlen
40*9880d681SAndroid Build Coastguard Worker# if HAVE_SYS_NDIR_H
41*9880d681SAndroid Build Coastguard Worker#  include <sys/ndir.h>
42*9880d681SAndroid Build Coastguard Worker# endif
43*9880d681SAndroid Build Coastguard Worker# if HAVE_SYS_DIR_H
44*9880d681SAndroid Build Coastguard Worker#  include <sys/dir.h>
45*9880d681SAndroid Build Coastguard Worker# endif
46*9880d681SAndroid Build Coastguard Worker# if HAVE_NDIR_H
47*9880d681SAndroid Build Coastguard Worker#  include <ndir.h>
48*9880d681SAndroid Build Coastguard Worker# endif
49*9880d681SAndroid Build Coastguard Worker#endif
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker#ifdef __APPLE__
52*9880d681SAndroid Build Coastguard Worker#include <mach-o/dyld.h>
53*9880d681SAndroid Build Coastguard Worker#include <sys/attr.h>
54*9880d681SAndroid Build Coastguard Worker#endif
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker// Both stdio.h and cstdio are included via different pathes and
57*9880d681SAndroid Build Coastguard Worker// stdcxx's cstdio doesn't include stdio.h, so it doesn't #undef the macros
58*9880d681SAndroid Build Coastguard Worker// either.
59*9880d681SAndroid Build Coastguard Worker#undef ferror
60*9880d681SAndroid Build Coastguard Worker#undef feof
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker// For GNU Hurd
63*9880d681SAndroid Build Coastguard Worker#if defined(__GNU__) && !defined(PATH_MAX)
64*9880d681SAndroid Build Coastguard Worker# define PATH_MAX 4096
65*9880d681SAndroid Build Coastguard Worker#endif
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker#include <sys/types.h>
68*9880d681SAndroid Build Coastguard Worker#if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__ANDROID__)
69*9880d681SAndroid Build Coastguard Worker#include <sys/statvfs.h>
70*9880d681SAndroid Build Coastguard Worker#define STATVFS statvfs
71*9880d681SAndroid Build Coastguard Worker#define STATVFS_F_FRSIZE(vfs) vfs.f_frsize
72*9880d681SAndroid Build Coastguard Worker#else
73*9880d681SAndroid Build Coastguard Worker#ifdef __OpenBSD__
74*9880d681SAndroid Build Coastguard Worker#include <sys/param.h>
75*9880d681SAndroid Build Coastguard Worker#include <sys/mount.h>
76*9880d681SAndroid Build Coastguard Worker#elif defined(__ANDROID__)
77*9880d681SAndroid Build Coastguard Worker#include <sys/vfs.h>
78*9880d681SAndroid Build Coastguard Worker#else
79*9880d681SAndroid Build Coastguard Worker#include <sys/mount.h>
80*9880d681SAndroid Build Coastguard Worker#endif
81*9880d681SAndroid Build Coastguard Worker#define STATVFS statfs
82*9880d681SAndroid Build Coastguard Worker#define STATVFS_F_FRSIZE(vfs) static_cast<uint64_t>(vfs.f_bsize)
83*9880d681SAndroid Build Coastguard Worker#endif
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Workerusing namespace llvm;
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Workernamespace llvm {
89*9880d681SAndroid Build Coastguard Workernamespace sys  {
90*9880d681SAndroid Build Coastguard Workernamespace fs {
91*9880d681SAndroid Build Coastguard Worker#if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
92*9880d681SAndroid Build Coastguard Worker    defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__) || \
93*9880d681SAndroid Build Coastguard Worker    defined(__linux__) || defined(__CYGWIN__) || defined(__DragonFly__)
94*9880d681SAndroid Build Coastguard Workerstatic int
95*9880d681SAndroid Build Coastguard Workertest_dir(char ret[PATH_MAX], const char *dir, const char *bin)
96*9880d681SAndroid Build Coastguard Worker{
97*9880d681SAndroid Build Coastguard Worker  struct stat sb;
98*9880d681SAndroid Build Coastguard Worker  char fullpath[PATH_MAX];
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Worker  snprintf(fullpath, PATH_MAX, "%s/%s", dir, bin);
101*9880d681SAndroid Build Coastguard Worker  if (!realpath(fullpath, ret))
102*9880d681SAndroid Build Coastguard Worker    return 1;
103*9880d681SAndroid Build Coastguard Worker  if (stat(fullpath, &sb) != 0)
104*9880d681SAndroid Build Coastguard Worker    return 1;
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker  return 0;
107*9880d681SAndroid Build Coastguard Worker}
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Workerstatic char *
110*9880d681SAndroid Build Coastguard Workergetprogpath(char ret[PATH_MAX], const char *bin)
111*9880d681SAndroid Build Coastguard Worker{
112*9880d681SAndroid Build Coastguard Worker  char *pv, *s, *t;
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker  /* First approach: absolute path. */
115*9880d681SAndroid Build Coastguard Worker  if (bin[0] == '/') {
116*9880d681SAndroid Build Coastguard Worker    if (test_dir(ret, "/", bin) == 0)
117*9880d681SAndroid Build Coastguard Worker      return ret;
118*9880d681SAndroid Build Coastguard Worker    return nullptr;
119*9880d681SAndroid Build Coastguard Worker  }
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Worker  /* Second approach: relative path. */
122*9880d681SAndroid Build Coastguard Worker  if (strchr(bin, '/')) {
123*9880d681SAndroid Build Coastguard Worker    char cwd[PATH_MAX];
124*9880d681SAndroid Build Coastguard Worker    if (!getcwd(cwd, PATH_MAX))
125*9880d681SAndroid Build Coastguard Worker      return nullptr;
126*9880d681SAndroid Build Coastguard Worker    if (test_dir(ret, cwd, bin) == 0)
127*9880d681SAndroid Build Coastguard Worker      return ret;
128*9880d681SAndroid Build Coastguard Worker    return nullptr;
129*9880d681SAndroid Build Coastguard Worker  }
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker  /* Third approach: $PATH */
132*9880d681SAndroid Build Coastguard Worker  if ((pv = getenv("PATH")) == nullptr)
133*9880d681SAndroid Build Coastguard Worker    return nullptr;
134*9880d681SAndroid Build Coastguard Worker  s = pv = strdup(pv);
135*9880d681SAndroid Build Coastguard Worker  if (!pv)
136*9880d681SAndroid Build Coastguard Worker    return nullptr;
137*9880d681SAndroid Build Coastguard Worker  while ((t = strsep(&s, ":")) != nullptr) {
138*9880d681SAndroid Build Coastguard Worker    if (test_dir(ret, t, bin) == 0) {
139*9880d681SAndroid Build Coastguard Worker      free(pv);
140*9880d681SAndroid Build Coastguard Worker      return ret;
141*9880d681SAndroid Build Coastguard Worker    }
142*9880d681SAndroid Build Coastguard Worker  }
143*9880d681SAndroid Build Coastguard Worker  free(pv);
144*9880d681SAndroid Build Coastguard Worker  return nullptr;
145*9880d681SAndroid Build Coastguard Worker}
146*9880d681SAndroid Build Coastguard Worker#endif // __FreeBSD__ || __NetBSD__ || __FreeBSD_kernel__
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker/// GetMainExecutable - Return the path to the main executable, given the
149*9880d681SAndroid Build Coastguard Worker/// value of argv[0] from program startup.
150*9880d681SAndroid Build Coastguard Workerstd::string getMainExecutable(const char *argv0, void *MainAddr) {
151*9880d681SAndroid Build Coastguard Worker#if defined(__APPLE__)
152*9880d681SAndroid Build Coastguard Worker  // On OS X the executable path is saved to the stack by dyld. Reading it
153*9880d681SAndroid Build Coastguard Worker  // from there is much faster than calling dladdr, especially for large
154*9880d681SAndroid Build Coastguard Worker  // binaries with symbols.
155*9880d681SAndroid Build Coastguard Worker  char exe_path[MAXPATHLEN];
156*9880d681SAndroid Build Coastguard Worker  uint32_t size = sizeof(exe_path);
157*9880d681SAndroid Build Coastguard Worker  if (_NSGetExecutablePath(exe_path, &size) == 0) {
158*9880d681SAndroid Build Coastguard Worker    char link_path[MAXPATHLEN];
159*9880d681SAndroid Build Coastguard Worker    if (realpath(exe_path, link_path))
160*9880d681SAndroid Build Coastguard Worker      return link_path;
161*9880d681SAndroid Build Coastguard Worker  }
162*9880d681SAndroid Build Coastguard Worker#elif defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
163*9880d681SAndroid Build Coastguard Worker      defined(__OpenBSD__) || defined(__minix) || defined(__DragonFly__) || \
164*9880d681SAndroid Build Coastguard Worker      defined(__FreeBSD_kernel__)
165*9880d681SAndroid Build Coastguard Worker  char exe_path[PATH_MAX];
166*9880d681SAndroid Build Coastguard Worker
167*9880d681SAndroid Build Coastguard Worker  if (getprogpath(exe_path, argv0) != NULL)
168*9880d681SAndroid Build Coastguard Worker    return exe_path;
169*9880d681SAndroid Build Coastguard Worker#elif defined(__linux__) || defined(__CYGWIN__)
170*9880d681SAndroid Build Coastguard Worker  char exe_path[MAXPATHLEN];
171*9880d681SAndroid Build Coastguard Worker  StringRef aPath("/proc/self/exe");
172*9880d681SAndroid Build Coastguard Worker  if (sys::fs::exists(aPath)) {
173*9880d681SAndroid Build Coastguard Worker      // /proc is not always mounted under Linux (chroot for example).
174*9880d681SAndroid Build Coastguard Worker      ssize_t len = readlink(aPath.str().c_str(), exe_path, sizeof(exe_path));
175*9880d681SAndroid Build Coastguard Worker      if (len >= 0)
176*9880d681SAndroid Build Coastguard Worker          return std::string(exe_path, len);
177*9880d681SAndroid Build Coastguard Worker  } else {
178*9880d681SAndroid Build Coastguard Worker      // Fall back to the classical detection.
179*9880d681SAndroid Build Coastguard Worker      if (getprogpath(exe_path, argv0))
180*9880d681SAndroid Build Coastguard Worker        return exe_path;
181*9880d681SAndroid Build Coastguard Worker  }
182*9880d681SAndroid Build Coastguard Worker#elif defined(HAVE_DLFCN_H)
183*9880d681SAndroid Build Coastguard Worker  // Use dladdr to get executable path if available.
184*9880d681SAndroid Build Coastguard Worker  Dl_info DLInfo;
185*9880d681SAndroid Build Coastguard Worker  int err = dladdr(MainAddr, &DLInfo);
186*9880d681SAndroid Build Coastguard Worker  if (err == 0)
187*9880d681SAndroid Build Coastguard Worker    return "";
188*9880d681SAndroid Build Coastguard Worker
189*9880d681SAndroid Build Coastguard Worker  // If the filename is a symlink, we need to resolve and return the location of
190*9880d681SAndroid Build Coastguard Worker  // the actual executable.
191*9880d681SAndroid Build Coastguard Worker  char link_path[MAXPATHLEN];
192*9880d681SAndroid Build Coastguard Worker  if (realpath(DLInfo.dli_fname, link_path))
193*9880d681SAndroid Build Coastguard Worker    return link_path;
194*9880d681SAndroid Build Coastguard Worker#else
195*9880d681SAndroid Build Coastguard Worker#error GetMainExecutable is not implemented on this host yet.
196*9880d681SAndroid Build Coastguard Worker#endif
197*9880d681SAndroid Build Coastguard Worker  return "";
198*9880d681SAndroid Build Coastguard Worker}
199*9880d681SAndroid Build Coastguard Worker
200*9880d681SAndroid Build Coastguard WorkerTimeValue file_status::getLastAccessedTime() const {
201*9880d681SAndroid Build Coastguard Worker  TimeValue Ret;
202*9880d681SAndroid Build Coastguard Worker  Ret.fromEpochTime(fs_st_atime);
203*9880d681SAndroid Build Coastguard Worker  return Ret;
204*9880d681SAndroid Build Coastguard Worker}
205*9880d681SAndroid Build Coastguard Worker
206*9880d681SAndroid Build Coastguard WorkerTimeValue file_status::getLastModificationTime() const {
207*9880d681SAndroid Build Coastguard Worker  TimeValue Ret;
208*9880d681SAndroid Build Coastguard Worker  Ret.fromEpochTime(fs_st_mtime);
209*9880d681SAndroid Build Coastguard Worker  return Ret;
210*9880d681SAndroid Build Coastguard Worker}
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard WorkerUniqueID file_status::getUniqueID() const {
213*9880d681SAndroid Build Coastguard Worker  return UniqueID(fs_st_dev, fs_st_ino);
214*9880d681SAndroid Build Coastguard Worker}
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard WorkerErrorOr<space_info> disk_space(const Twine &Path) {
217*9880d681SAndroid Build Coastguard Worker  struct STATVFS Vfs;
218*9880d681SAndroid Build Coastguard Worker  if (::STATVFS(Path.str().c_str(), &Vfs))
219*9880d681SAndroid Build Coastguard Worker    return std::error_code(errno, std::generic_category());
220*9880d681SAndroid Build Coastguard Worker  auto FrSize = STATVFS_F_FRSIZE(Vfs);
221*9880d681SAndroid Build Coastguard Worker  space_info SpaceInfo;
222*9880d681SAndroid Build Coastguard Worker  SpaceInfo.capacity = static_cast<uint64_t>(Vfs.f_blocks) * FrSize;
223*9880d681SAndroid Build Coastguard Worker  SpaceInfo.free = static_cast<uint64_t>(Vfs.f_bfree) * FrSize;
224*9880d681SAndroid Build Coastguard Worker  SpaceInfo.available = static_cast<uint64_t>(Vfs.f_bavail) * FrSize;
225*9880d681SAndroid Build Coastguard Worker  return SpaceInfo;
226*9880d681SAndroid Build Coastguard Worker}
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Workerstd::error_code current_path(SmallVectorImpl<char> &result) {
229*9880d681SAndroid Build Coastguard Worker  result.clear();
230*9880d681SAndroid Build Coastguard Worker
231*9880d681SAndroid Build Coastguard Worker  const char *pwd = ::getenv("PWD");
232*9880d681SAndroid Build Coastguard Worker  llvm::sys::fs::file_status PWDStatus, DotStatus;
233*9880d681SAndroid Build Coastguard Worker  if (pwd && llvm::sys::path::is_absolute(pwd) &&
234*9880d681SAndroid Build Coastguard Worker      !llvm::sys::fs::status(pwd, PWDStatus) &&
235*9880d681SAndroid Build Coastguard Worker      !llvm::sys::fs::status(".", DotStatus) &&
236*9880d681SAndroid Build Coastguard Worker      PWDStatus.getUniqueID() == DotStatus.getUniqueID()) {
237*9880d681SAndroid Build Coastguard Worker    result.append(pwd, pwd + strlen(pwd));
238*9880d681SAndroid Build Coastguard Worker    return std::error_code();
239*9880d681SAndroid Build Coastguard Worker  }
240*9880d681SAndroid Build Coastguard Worker
241*9880d681SAndroid Build Coastguard Worker#ifdef MAXPATHLEN
242*9880d681SAndroid Build Coastguard Worker  result.reserve(MAXPATHLEN);
243*9880d681SAndroid Build Coastguard Worker#else
244*9880d681SAndroid Build Coastguard Worker// For GNU Hurd
245*9880d681SAndroid Build Coastguard Worker  result.reserve(1024);
246*9880d681SAndroid Build Coastguard Worker#endif
247*9880d681SAndroid Build Coastguard Worker
248*9880d681SAndroid Build Coastguard Worker  while (true) {
249*9880d681SAndroid Build Coastguard Worker    if (::getcwd(result.data(), result.capacity()) == nullptr) {
250*9880d681SAndroid Build Coastguard Worker      // See if there was a real error.
251*9880d681SAndroid Build Coastguard Worker      if (errno != ENOMEM)
252*9880d681SAndroid Build Coastguard Worker        return std::error_code(errno, std::generic_category());
253*9880d681SAndroid Build Coastguard Worker      // Otherwise there just wasn't enough space.
254*9880d681SAndroid Build Coastguard Worker      result.reserve(result.capacity() * 2);
255*9880d681SAndroid Build Coastguard Worker    } else
256*9880d681SAndroid Build Coastguard Worker      break;
257*9880d681SAndroid Build Coastguard Worker  }
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker  result.set_size(strlen(result.data()));
260*9880d681SAndroid Build Coastguard Worker  return std::error_code();
261*9880d681SAndroid Build Coastguard Worker}
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Workerstd::error_code create_directory(const Twine &path, bool IgnoreExisting,
264*9880d681SAndroid Build Coastguard Worker                                 perms Perms) {
265*9880d681SAndroid Build Coastguard Worker  SmallString<128> path_storage;
266*9880d681SAndroid Build Coastguard Worker  StringRef p = path.toNullTerminatedStringRef(path_storage);
267*9880d681SAndroid Build Coastguard Worker
268*9880d681SAndroid Build Coastguard Worker  if (::mkdir(p.begin(), Perms) == -1) {
269*9880d681SAndroid Build Coastguard Worker    if (errno != EEXIST || !IgnoreExisting)
270*9880d681SAndroid Build Coastguard Worker      return std::error_code(errno, std::generic_category());
271*9880d681SAndroid Build Coastguard Worker  }
272*9880d681SAndroid Build Coastguard Worker
273*9880d681SAndroid Build Coastguard Worker  return std::error_code();
274*9880d681SAndroid Build Coastguard Worker}
275*9880d681SAndroid Build Coastguard Worker
276*9880d681SAndroid Build Coastguard Worker// Note that we are using symbolic link because hard links are not supported by
277*9880d681SAndroid Build Coastguard Worker// all filesystems (SMB doesn't).
278*9880d681SAndroid Build Coastguard Workerstd::error_code create_link(const Twine &to, const Twine &from) {
279*9880d681SAndroid Build Coastguard Worker  // Get arguments.
280*9880d681SAndroid Build Coastguard Worker  SmallString<128> from_storage;
281*9880d681SAndroid Build Coastguard Worker  SmallString<128> to_storage;
282*9880d681SAndroid Build Coastguard Worker  StringRef f = from.toNullTerminatedStringRef(from_storage);
283*9880d681SAndroid Build Coastguard Worker  StringRef t = to.toNullTerminatedStringRef(to_storage);
284*9880d681SAndroid Build Coastguard Worker
285*9880d681SAndroid Build Coastguard Worker  if (::symlink(t.begin(), f.begin()) == -1)
286*9880d681SAndroid Build Coastguard Worker    return std::error_code(errno, std::generic_category());
287*9880d681SAndroid Build Coastguard Worker
288*9880d681SAndroid Build Coastguard Worker  return std::error_code();
289*9880d681SAndroid Build Coastguard Worker}
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard Workerstd::error_code remove(const Twine &path, bool IgnoreNonExisting) {
292*9880d681SAndroid Build Coastguard Worker  SmallString<128> path_storage;
293*9880d681SAndroid Build Coastguard Worker  StringRef p = path.toNullTerminatedStringRef(path_storage);
294*9880d681SAndroid Build Coastguard Worker
295*9880d681SAndroid Build Coastguard Worker  struct stat buf;
296*9880d681SAndroid Build Coastguard Worker  if (lstat(p.begin(), &buf) != 0) {
297*9880d681SAndroid Build Coastguard Worker    if (errno != ENOENT || !IgnoreNonExisting)
298*9880d681SAndroid Build Coastguard Worker      return std::error_code(errno, std::generic_category());
299*9880d681SAndroid Build Coastguard Worker    return std::error_code();
300*9880d681SAndroid Build Coastguard Worker  }
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Worker  // Note: this check catches strange situations. In all cases, LLVM should
303*9880d681SAndroid Build Coastguard Worker  // only be involved in the creation and deletion of regular files.  This
304*9880d681SAndroid Build Coastguard Worker  // check ensures that what we're trying to erase is a regular file. It
305*9880d681SAndroid Build Coastguard Worker  // effectively prevents LLVM from erasing things like /dev/null, any block
306*9880d681SAndroid Build Coastguard Worker  // special file, or other things that aren't "regular" files.
307*9880d681SAndroid Build Coastguard Worker  if (!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode) && !S_ISLNK(buf.st_mode))
308*9880d681SAndroid Build Coastguard Worker    return make_error_code(errc::operation_not_permitted);
309*9880d681SAndroid Build Coastguard Worker
310*9880d681SAndroid Build Coastguard Worker  if (::remove(p.begin()) == -1) {
311*9880d681SAndroid Build Coastguard Worker    if (errno != ENOENT || !IgnoreNonExisting)
312*9880d681SAndroid Build Coastguard Worker      return std::error_code(errno, std::generic_category());
313*9880d681SAndroid Build Coastguard Worker  }
314*9880d681SAndroid Build Coastguard Worker
315*9880d681SAndroid Build Coastguard Worker  return std::error_code();
316*9880d681SAndroid Build Coastguard Worker}
317*9880d681SAndroid Build Coastguard Worker
318*9880d681SAndroid Build Coastguard Workerstd::error_code rename(const Twine &from, const Twine &to) {
319*9880d681SAndroid Build Coastguard Worker  // Get arguments.
320*9880d681SAndroid Build Coastguard Worker  SmallString<128> from_storage;
321*9880d681SAndroid Build Coastguard Worker  SmallString<128> to_storage;
322*9880d681SAndroid Build Coastguard Worker  StringRef f = from.toNullTerminatedStringRef(from_storage);
323*9880d681SAndroid Build Coastguard Worker  StringRef t = to.toNullTerminatedStringRef(to_storage);
324*9880d681SAndroid Build Coastguard Worker
325*9880d681SAndroid Build Coastguard Worker  if (::rename(f.begin(), t.begin()) == -1)
326*9880d681SAndroid Build Coastguard Worker    return std::error_code(errno, std::generic_category());
327*9880d681SAndroid Build Coastguard Worker
328*9880d681SAndroid Build Coastguard Worker  return std::error_code();
329*9880d681SAndroid Build Coastguard Worker}
330*9880d681SAndroid Build Coastguard Worker
331*9880d681SAndroid Build Coastguard Workerstd::error_code resize_file(int FD, uint64_t Size) {
332*9880d681SAndroid Build Coastguard Worker  if (::ftruncate(FD, Size) == -1)
333*9880d681SAndroid Build Coastguard Worker    return std::error_code(errno, std::generic_category());
334*9880d681SAndroid Build Coastguard Worker
335*9880d681SAndroid Build Coastguard Worker  return std::error_code();
336*9880d681SAndroid Build Coastguard Worker}
337*9880d681SAndroid Build Coastguard Worker
338*9880d681SAndroid Build Coastguard Workerstatic int convertAccessMode(AccessMode Mode) {
339*9880d681SAndroid Build Coastguard Worker  switch (Mode) {
340*9880d681SAndroid Build Coastguard Worker  case AccessMode::Exist:
341*9880d681SAndroid Build Coastguard Worker    return F_OK;
342*9880d681SAndroid Build Coastguard Worker  case AccessMode::Write:
343*9880d681SAndroid Build Coastguard Worker    return W_OK;
344*9880d681SAndroid Build Coastguard Worker  case AccessMode::Execute:
345*9880d681SAndroid Build Coastguard Worker    return R_OK | X_OK; // scripts also need R_OK.
346*9880d681SAndroid Build Coastguard Worker  }
347*9880d681SAndroid Build Coastguard Worker  llvm_unreachable("invalid enum");
348*9880d681SAndroid Build Coastguard Worker}
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Workerstd::error_code access(const Twine &Path, AccessMode Mode) {
351*9880d681SAndroid Build Coastguard Worker  SmallString<128> PathStorage;
352*9880d681SAndroid Build Coastguard Worker  StringRef P = Path.toNullTerminatedStringRef(PathStorage);
353*9880d681SAndroid Build Coastguard Worker
354*9880d681SAndroid Build Coastguard Worker  if (::access(P.begin(), convertAccessMode(Mode)) == -1)
355*9880d681SAndroid Build Coastguard Worker    return std::error_code(errno, std::generic_category());
356*9880d681SAndroid Build Coastguard Worker
357*9880d681SAndroid Build Coastguard Worker  if (Mode == AccessMode::Execute) {
358*9880d681SAndroid Build Coastguard Worker    // Don't say that directories are executable.
359*9880d681SAndroid Build Coastguard Worker    struct stat buf;
360*9880d681SAndroid Build Coastguard Worker    if (0 != stat(P.begin(), &buf))
361*9880d681SAndroid Build Coastguard Worker      return errc::permission_denied;
362*9880d681SAndroid Build Coastguard Worker    if (!S_ISREG(buf.st_mode))
363*9880d681SAndroid Build Coastguard Worker      return errc::permission_denied;
364*9880d681SAndroid Build Coastguard Worker  }
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker  return std::error_code();
367*9880d681SAndroid Build Coastguard Worker}
368*9880d681SAndroid Build Coastguard Worker
369*9880d681SAndroid Build Coastguard Workerbool can_execute(const Twine &Path) {
370*9880d681SAndroid Build Coastguard Worker  return !access(Path, AccessMode::Execute);
371*9880d681SAndroid Build Coastguard Worker}
372*9880d681SAndroid Build Coastguard Worker
373*9880d681SAndroid Build Coastguard Workerbool equivalent(file_status A, file_status B) {
374*9880d681SAndroid Build Coastguard Worker  assert(status_known(A) && status_known(B));
375*9880d681SAndroid Build Coastguard Worker  return A.fs_st_dev == B.fs_st_dev &&
376*9880d681SAndroid Build Coastguard Worker         A.fs_st_ino == B.fs_st_ino;
377*9880d681SAndroid Build Coastguard Worker}
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Workerstd::error_code equivalent(const Twine &A, const Twine &B, bool &result) {
380*9880d681SAndroid Build Coastguard Worker  file_status fsA, fsB;
381*9880d681SAndroid Build Coastguard Worker  if (std::error_code ec = status(A, fsA))
382*9880d681SAndroid Build Coastguard Worker    return ec;
383*9880d681SAndroid Build Coastguard Worker  if (std::error_code ec = status(B, fsB))
384*9880d681SAndroid Build Coastguard Worker    return ec;
385*9880d681SAndroid Build Coastguard Worker  result = equivalent(fsA, fsB);
386*9880d681SAndroid Build Coastguard Worker  return std::error_code();
387*9880d681SAndroid Build Coastguard Worker}
388*9880d681SAndroid Build Coastguard Worker
389*9880d681SAndroid Build Coastguard Workerstatic std::error_code fillStatus(int StatRet, const struct stat &Status,
390*9880d681SAndroid Build Coastguard Worker                             file_status &Result) {
391*9880d681SAndroid Build Coastguard Worker  if (StatRet != 0) {
392*9880d681SAndroid Build Coastguard Worker    std::error_code ec(errno, std::generic_category());
393*9880d681SAndroid Build Coastguard Worker    if (ec == errc::no_such_file_or_directory)
394*9880d681SAndroid Build Coastguard Worker      Result = file_status(file_type::file_not_found);
395*9880d681SAndroid Build Coastguard Worker    else
396*9880d681SAndroid Build Coastguard Worker      Result = file_status(file_type::status_error);
397*9880d681SAndroid Build Coastguard Worker    return ec;
398*9880d681SAndroid Build Coastguard Worker  }
399*9880d681SAndroid Build Coastguard Worker
400*9880d681SAndroid Build Coastguard Worker  file_type Type = file_type::type_unknown;
401*9880d681SAndroid Build Coastguard Worker
402*9880d681SAndroid Build Coastguard Worker  if (S_ISDIR(Status.st_mode))
403*9880d681SAndroid Build Coastguard Worker    Type = file_type::directory_file;
404*9880d681SAndroid Build Coastguard Worker  else if (S_ISREG(Status.st_mode))
405*9880d681SAndroid Build Coastguard Worker    Type = file_type::regular_file;
406*9880d681SAndroid Build Coastguard Worker  else if (S_ISBLK(Status.st_mode))
407*9880d681SAndroid Build Coastguard Worker    Type = file_type::block_file;
408*9880d681SAndroid Build Coastguard Worker  else if (S_ISCHR(Status.st_mode))
409*9880d681SAndroid Build Coastguard Worker    Type = file_type::character_file;
410*9880d681SAndroid Build Coastguard Worker  else if (S_ISFIFO(Status.st_mode))
411*9880d681SAndroid Build Coastguard Worker    Type = file_type::fifo_file;
412*9880d681SAndroid Build Coastguard Worker  else if (S_ISSOCK(Status.st_mode))
413*9880d681SAndroid Build Coastguard Worker    Type = file_type::socket_file;
414*9880d681SAndroid Build Coastguard Worker
415*9880d681SAndroid Build Coastguard Worker  perms Perms = static_cast<perms>(Status.st_mode);
416*9880d681SAndroid Build Coastguard Worker  Result =
417*9880d681SAndroid Build Coastguard Worker      file_status(Type, Perms, Status.st_dev, Status.st_ino, Status.st_atime,
418*9880d681SAndroid Build Coastguard Worker                  Status.st_mtime, Status.st_uid, Status.st_gid,
419*9880d681SAndroid Build Coastguard Worker                  Status.st_size);
420*9880d681SAndroid Build Coastguard Worker
421*9880d681SAndroid Build Coastguard Worker  return std::error_code();
422*9880d681SAndroid Build Coastguard Worker}
423*9880d681SAndroid Build Coastguard Worker
424*9880d681SAndroid Build Coastguard Workerstd::error_code status(const Twine &Path, file_status &Result) {
425*9880d681SAndroid Build Coastguard Worker  SmallString<128> PathStorage;
426*9880d681SAndroid Build Coastguard Worker  StringRef P = Path.toNullTerminatedStringRef(PathStorage);
427*9880d681SAndroid Build Coastguard Worker
428*9880d681SAndroid Build Coastguard Worker  struct stat Status;
429*9880d681SAndroid Build Coastguard Worker  int StatRet = ::stat(P.begin(), &Status);
430*9880d681SAndroid Build Coastguard Worker  return fillStatus(StatRet, Status, Result);
431*9880d681SAndroid Build Coastguard Worker}
432*9880d681SAndroid Build Coastguard Worker
433*9880d681SAndroid Build Coastguard Workerstd::error_code status(int FD, file_status &Result) {
434*9880d681SAndroid Build Coastguard Worker  struct stat Status;
435*9880d681SAndroid Build Coastguard Worker  int StatRet = ::fstat(FD, &Status);
436*9880d681SAndroid Build Coastguard Worker  return fillStatus(StatRet, Status, Result);
437*9880d681SAndroid Build Coastguard Worker}
438*9880d681SAndroid Build Coastguard Worker
439*9880d681SAndroid Build Coastguard Workerstd::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
440*9880d681SAndroid Build Coastguard Worker#if defined(HAVE_FUTIMENS)
441*9880d681SAndroid Build Coastguard Worker  timespec Times[2];
442*9880d681SAndroid Build Coastguard Worker  Times[0].tv_sec = Time.toEpochTime();
443*9880d681SAndroid Build Coastguard Worker  Times[0].tv_nsec = 0;
444*9880d681SAndroid Build Coastguard Worker  Times[1] = Times[0];
445*9880d681SAndroid Build Coastguard Worker  if (::futimens(FD, Times))
446*9880d681SAndroid Build Coastguard Worker    return std::error_code(errno, std::generic_category());
447*9880d681SAndroid Build Coastguard Worker  return std::error_code();
448*9880d681SAndroid Build Coastguard Worker#elif defined(HAVE_FUTIMES)
449*9880d681SAndroid Build Coastguard Worker  timeval Times[2];
450*9880d681SAndroid Build Coastguard Worker  Times[0].tv_sec = Time.toEpochTime();
451*9880d681SAndroid Build Coastguard Worker  Times[0].tv_usec = 0;
452*9880d681SAndroid Build Coastguard Worker  Times[1] = Times[0];
453*9880d681SAndroid Build Coastguard Worker  if (::futimes(FD, Times))
454*9880d681SAndroid Build Coastguard Worker    return std::error_code(errno, std::generic_category());
455*9880d681SAndroid Build Coastguard Worker  return std::error_code();
456*9880d681SAndroid Build Coastguard Worker#else
457*9880d681SAndroid Build Coastguard Worker#warning Missing futimes() and futimens()
458*9880d681SAndroid Build Coastguard Worker  return make_error_code(errc::function_not_supported);
459*9880d681SAndroid Build Coastguard Worker#endif
460*9880d681SAndroid Build Coastguard Worker}
461*9880d681SAndroid Build Coastguard Worker
462*9880d681SAndroid Build Coastguard Workerstd::error_code mapped_file_region::init(int FD, uint64_t Offset,
463*9880d681SAndroid Build Coastguard Worker                                         mapmode Mode) {
464*9880d681SAndroid Build Coastguard Worker  assert(Size != 0);
465*9880d681SAndroid Build Coastguard Worker
466*9880d681SAndroid Build Coastguard Worker  int flags = (Mode == readwrite) ? MAP_SHARED : MAP_PRIVATE;
467*9880d681SAndroid Build Coastguard Worker  int prot = (Mode == readonly) ? PROT_READ : (PROT_READ | PROT_WRITE);
468*9880d681SAndroid Build Coastguard Worker  Mapping = ::mmap(nullptr, Size, prot, flags, FD, Offset);
469*9880d681SAndroid Build Coastguard Worker  if (Mapping == MAP_FAILED)
470*9880d681SAndroid Build Coastguard Worker    return std::error_code(errno, std::generic_category());
471*9880d681SAndroid Build Coastguard Worker  return std::error_code();
472*9880d681SAndroid Build Coastguard Worker}
473*9880d681SAndroid Build Coastguard Worker
474*9880d681SAndroid Build Coastguard Workermapped_file_region::mapped_file_region(int fd, mapmode mode, uint64_t length,
475*9880d681SAndroid Build Coastguard Worker                                       uint64_t offset, std::error_code &ec)
476*9880d681SAndroid Build Coastguard Worker    : Size(length), Mapping() {
477*9880d681SAndroid Build Coastguard Worker  // Make sure that the requested size fits within SIZE_T.
478*9880d681SAndroid Build Coastguard Worker  if (length > std::numeric_limits<size_t>::max()) {
479*9880d681SAndroid Build Coastguard Worker    ec = make_error_code(errc::invalid_argument);
480*9880d681SAndroid Build Coastguard Worker    return;
481*9880d681SAndroid Build Coastguard Worker  }
482*9880d681SAndroid Build Coastguard Worker
483*9880d681SAndroid Build Coastguard Worker  ec = init(fd, offset, mode);
484*9880d681SAndroid Build Coastguard Worker  if (ec)
485*9880d681SAndroid Build Coastguard Worker    Mapping = nullptr;
486*9880d681SAndroid Build Coastguard Worker}
487*9880d681SAndroid Build Coastguard Worker
488*9880d681SAndroid Build Coastguard Workermapped_file_region::~mapped_file_region() {
489*9880d681SAndroid Build Coastguard Worker  if (Mapping)
490*9880d681SAndroid Build Coastguard Worker    ::munmap(Mapping, Size);
491*9880d681SAndroid Build Coastguard Worker}
492*9880d681SAndroid Build Coastguard Worker
493*9880d681SAndroid Build Coastguard Workeruint64_t mapped_file_region::size() const {
494*9880d681SAndroid Build Coastguard Worker  assert(Mapping && "Mapping failed but used anyway!");
495*9880d681SAndroid Build Coastguard Worker  return Size;
496*9880d681SAndroid Build Coastguard Worker}
497*9880d681SAndroid Build Coastguard Worker
498*9880d681SAndroid Build Coastguard Workerchar *mapped_file_region::data() const {
499*9880d681SAndroid Build Coastguard Worker  assert(Mapping && "Mapping failed but used anyway!");
500*9880d681SAndroid Build Coastguard Worker  return reinterpret_cast<char*>(Mapping);
501*9880d681SAndroid Build Coastguard Worker}
502*9880d681SAndroid Build Coastguard Worker
503*9880d681SAndroid Build Coastguard Workerconst char *mapped_file_region::const_data() const {
504*9880d681SAndroid Build Coastguard Worker  assert(Mapping && "Mapping failed but used anyway!");
505*9880d681SAndroid Build Coastguard Worker  return reinterpret_cast<const char*>(Mapping);
506*9880d681SAndroid Build Coastguard Worker}
507*9880d681SAndroid Build Coastguard Worker
508*9880d681SAndroid Build Coastguard Workerint mapped_file_region::alignment() {
509*9880d681SAndroid Build Coastguard Worker  return Process::getPageSize();
510*9880d681SAndroid Build Coastguard Worker}
511*9880d681SAndroid Build Coastguard Worker
512*9880d681SAndroid Build Coastguard Workerstd::error_code detail::directory_iterator_construct(detail::DirIterState &it,
513*9880d681SAndroid Build Coastguard Worker                                                StringRef path){
514*9880d681SAndroid Build Coastguard Worker  SmallString<128> path_null(path);
515*9880d681SAndroid Build Coastguard Worker  DIR *directory = ::opendir(path_null.c_str());
516*9880d681SAndroid Build Coastguard Worker  if (!directory)
517*9880d681SAndroid Build Coastguard Worker    return std::error_code(errno, std::generic_category());
518*9880d681SAndroid Build Coastguard Worker
519*9880d681SAndroid Build Coastguard Worker  it.IterationHandle = reinterpret_cast<intptr_t>(directory);
520*9880d681SAndroid Build Coastguard Worker  // Add something for replace_filename to replace.
521*9880d681SAndroid Build Coastguard Worker  path::append(path_null, ".");
522*9880d681SAndroid Build Coastguard Worker  it.CurrentEntry = directory_entry(path_null.str());
523*9880d681SAndroid Build Coastguard Worker  return directory_iterator_increment(it);
524*9880d681SAndroid Build Coastguard Worker}
525*9880d681SAndroid Build Coastguard Worker
526*9880d681SAndroid Build Coastguard Workerstd::error_code detail::directory_iterator_destruct(detail::DirIterState &it) {
527*9880d681SAndroid Build Coastguard Worker  if (it.IterationHandle)
528*9880d681SAndroid Build Coastguard Worker    ::closedir(reinterpret_cast<DIR *>(it.IterationHandle));
529*9880d681SAndroid Build Coastguard Worker  it.IterationHandle = 0;
530*9880d681SAndroid Build Coastguard Worker  it.CurrentEntry = directory_entry();
531*9880d681SAndroid Build Coastguard Worker  return std::error_code();
532*9880d681SAndroid Build Coastguard Worker}
533*9880d681SAndroid Build Coastguard Worker
534*9880d681SAndroid Build Coastguard Workerstd::error_code detail::directory_iterator_increment(detail::DirIterState &it) {
535*9880d681SAndroid Build Coastguard Worker  errno = 0;
536*9880d681SAndroid Build Coastguard Worker  dirent *cur_dir = ::readdir(reinterpret_cast<DIR *>(it.IterationHandle));
537*9880d681SAndroid Build Coastguard Worker  if (cur_dir == nullptr && errno != 0) {
538*9880d681SAndroid Build Coastguard Worker    return std::error_code(errno, std::generic_category());
539*9880d681SAndroid Build Coastguard Worker  } else if (cur_dir != nullptr) {
540*9880d681SAndroid Build Coastguard Worker    StringRef name(cur_dir->d_name, NAMLEN(cur_dir));
541*9880d681SAndroid Build Coastguard Worker    if ((name.size() == 1 && name[0] == '.') ||
542*9880d681SAndroid Build Coastguard Worker        (name.size() == 2 && name[0] == '.' && name[1] == '.'))
543*9880d681SAndroid Build Coastguard Worker      return directory_iterator_increment(it);
544*9880d681SAndroid Build Coastguard Worker    it.CurrentEntry.replace_filename(name);
545*9880d681SAndroid Build Coastguard Worker  } else
546*9880d681SAndroid Build Coastguard Worker    return directory_iterator_destruct(it);
547*9880d681SAndroid Build Coastguard Worker
548*9880d681SAndroid Build Coastguard Worker  return std::error_code();
549*9880d681SAndroid Build Coastguard Worker}
550*9880d681SAndroid Build Coastguard Worker
551*9880d681SAndroid Build Coastguard Worker#if !defined(F_GETPATH)
552*9880d681SAndroid Build Coastguard Workerstatic bool hasProcSelfFD() {
553*9880d681SAndroid Build Coastguard Worker  // If we have a /proc filesystem mounted, we can quickly establish the
554*9880d681SAndroid Build Coastguard Worker  // real name of the file with readlink
555*9880d681SAndroid Build Coastguard Worker  static const bool Result = (::access("/proc/self/fd", R_OK) == 0);
556*9880d681SAndroid Build Coastguard Worker  return Result;
557*9880d681SAndroid Build Coastguard Worker}
558*9880d681SAndroid Build Coastguard Worker#endif
559*9880d681SAndroid Build Coastguard Worker
560*9880d681SAndroid Build Coastguard Workerstd::error_code openFileForRead(const Twine &Name, int &ResultFD,
561*9880d681SAndroid Build Coastguard Worker                                SmallVectorImpl<char> *RealPath) {
562*9880d681SAndroid Build Coastguard Worker  SmallString<128> Storage;
563*9880d681SAndroid Build Coastguard Worker  StringRef P = Name.toNullTerminatedStringRef(Storage);
564*9880d681SAndroid Build Coastguard Worker  while ((ResultFD = open(P.begin(), O_RDONLY)) < 0) {
565*9880d681SAndroid Build Coastguard Worker    if (errno != EINTR)
566*9880d681SAndroid Build Coastguard Worker      return std::error_code(errno, std::generic_category());
567*9880d681SAndroid Build Coastguard Worker  }
568*9880d681SAndroid Build Coastguard Worker  // Attempt to get the real name of the file, if the user asked
569*9880d681SAndroid Build Coastguard Worker  if(!RealPath)
570*9880d681SAndroid Build Coastguard Worker    return std::error_code();
571*9880d681SAndroid Build Coastguard Worker  RealPath->clear();
572*9880d681SAndroid Build Coastguard Worker#if defined(F_GETPATH)
573*9880d681SAndroid Build Coastguard Worker  // When F_GETPATH is availble, it is the quickest way to get
574*9880d681SAndroid Build Coastguard Worker  // the real path name.
575*9880d681SAndroid Build Coastguard Worker  char Buffer[MAXPATHLEN];
576*9880d681SAndroid Build Coastguard Worker  if (::fcntl(ResultFD, F_GETPATH, Buffer) != -1)
577*9880d681SAndroid Build Coastguard Worker    RealPath->append(Buffer, Buffer + strlen(Buffer));
578*9880d681SAndroid Build Coastguard Worker#else
579*9880d681SAndroid Build Coastguard Worker  char Buffer[PATH_MAX];
580*9880d681SAndroid Build Coastguard Worker  if (hasProcSelfFD()) {
581*9880d681SAndroid Build Coastguard Worker    char ProcPath[64];
582*9880d681SAndroid Build Coastguard Worker    snprintf(ProcPath, sizeof(ProcPath), "/proc/self/fd/%d", ResultFD);
583*9880d681SAndroid Build Coastguard Worker    ssize_t CharCount = ::readlink(ProcPath, Buffer, sizeof(Buffer));
584*9880d681SAndroid Build Coastguard Worker    if (CharCount > 0)
585*9880d681SAndroid Build Coastguard Worker      RealPath->append(Buffer, Buffer + CharCount);
586*9880d681SAndroid Build Coastguard Worker  } else {
587*9880d681SAndroid Build Coastguard Worker    // Use ::realpath to get the real path name
588*9880d681SAndroid Build Coastguard Worker    if (::realpath(P.begin(), Buffer) != nullptr)
589*9880d681SAndroid Build Coastguard Worker      RealPath->append(Buffer, Buffer + strlen(Buffer));
590*9880d681SAndroid Build Coastguard Worker  }
591*9880d681SAndroid Build Coastguard Worker#endif
592*9880d681SAndroid Build Coastguard Worker  return std::error_code();
593*9880d681SAndroid Build Coastguard Worker}
594*9880d681SAndroid Build Coastguard Worker
595*9880d681SAndroid Build Coastguard Workerstd::error_code openFileForWrite(const Twine &Name, int &ResultFD,
596*9880d681SAndroid Build Coastguard Worker                            sys::fs::OpenFlags Flags, unsigned Mode) {
597*9880d681SAndroid Build Coastguard Worker  // Verify that we don't have both "append" and "excl".
598*9880d681SAndroid Build Coastguard Worker  assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) &&
599*9880d681SAndroid Build Coastguard Worker         "Cannot specify both 'excl' and 'append' file creation flags!");
600*9880d681SAndroid Build Coastguard Worker
601*9880d681SAndroid Build Coastguard Worker  int OpenFlags = O_CREAT;
602*9880d681SAndroid Build Coastguard Worker
603*9880d681SAndroid Build Coastguard Worker  if (Flags & F_RW)
604*9880d681SAndroid Build Coastguard Worker    OpenFlags |= O_RDWR;
605*9880d681SAndroid Build Coastguard Worker  else
606*9880d681SAndroid Build Coastguard Worker    OpenFlags |= O_WRONLY;
607*9880d681SAndroid Build Coastguard Worker
608*9880d681SAndroid Build Coastguard Worker  if (Flags & F_Append)
609*9880d681SAndroid Build Coastguard Worker    OpenFlags |= O_APPEND;
610*9880d681SAndroid Build Coastguard Worker  else
611*9880d681SAndroid Build Coastguard Worker    OpenFlags |= O_TRUNC;
612*9880d681SAndroid Build Coastguard Worker
613*9880d681SAndroid Build Coastguard Worker  if (Flags & F_Excl)
614*9880d681SAndroid Build Coastguard Worker    OpenFlags |= O_EXCL;
615*9880d681SAndroid Build Coastguard Worker
616*9880d681SAndroid Build Coastguard Worker  SmallString<128> Storage;
617*9880d681SAndroid Build Coastguard Worker  StringRef P = Name.toNullTerminatedStringRef(Storage);
618*9880d681SAndroid Build Coastguard Worker  while ((ResultFD = open(P.begin(), OpenFlags, Mode)) < 0) {
619*9880d681SAndroid Build Coastguard Worker    if (errno != EINTR)
620*9880d681SAndroid Build Coastguard Worker      return std::error_code(errno, std::generic_category());
621*9880d681SAndroid Build Coastguard Worker  }
622*9880d681SAndroid Build Coastguard Worker  return std::error_code();
623*9880d681SAndroid Build Coastguard Worker}
624*9880d681SAndroid Build Coastguard Worker
625*9880d681SAndroid Build Coastguard Workerstd::error_code getPathFromOpenFD(int FD, SmallVectorImpl<char> &ResultPath) {
626*9880d681SAndroid Build Coastguard Worker  if (FD < 0)
627*9880d681SAndroid Build Coastguard Worker    return make_error_code(errc::bad_file_descriptor);
628*9880d681SAndroid Build Coastguard Worker
629*9880d681SAndroid Build Coastguard Worker#if defined(F_GETPATH)
630*9880d681SAndroid Build Coastguard Worker  // When F_GETPATH is availble, it is the quickest way to get
631*9880d681SAndroid Build Coastguard Worker  // the path from a file descriptor.
632*9880d681SAndroid Build Coastguard Worker  ResultPath.reserve(MAXPATHLEN);
633*9880d681SAndroid Build Coastguard Worker  if (::fcntl(FD, F_GETPATH, ResultPath.begin()) == -1)
634*9880d681SAndroid Build Coastguard Worker    return std::error_code(errno, std::generic_category());
635*9880d681SAndroid Build Coastguard Worker
636*9880d681SAndroid Build Coastguard Worker  ResultPath.set_size(strlen(ResultPath.begin()));
637*9880d681SAndroid Build Coastguard Worker#else
638*9880d681SAndroid Build Coastguard Worker  // If we have a /proc filesystem mounted, we can quickly establish the
639*9880d681SAndroid Build Coastguard Worker  // real name of the file with readlink. Otherwise, we don't know how to
640*9880d681SAndroid Build Coastguard Worker  // get the filename from a file descriptor. Give up.
641*9880d681SAndroid Build Coastguard Worker  if (!fs::hasProcSelfFD())
642*9880d681SAndroid Build Coastguard Worker    return make_error_code(errc::function_not_supported);
643*9880d681SAndroid Build Coastguard Worker
644*9880d681SAndroid Build Coastguard Worker  ResultPath.reserve(PATH_MAX);
645*9880d681SAndroid Build Coastguard Worker  char ProcPath[64];
646*9880d681SAndroid Build Coastguard Worker  snprintf(ProcPath, sizeof(ProcPath), "/proc/self/fd/%d", FD);
647*9880d681SAndroid Build Coastguard Worker  ssize_t CharCount = ::readlink(ProcPath, ResultPath.begin(), ResultPath.capacity());
648*9880d681SAndroid Build Coastguard Worker  if (CharCount < 0)
649*9880d681SAndroid Build Coastguard Worker      return std::error_code(errno, std::generic_category());
650*9880d681SAndroid Build Coastguard Worker
651*9880d681SAndroid Build Coastguard Worker  // Was the filename truncated?
652*9880d681SAndroid Build Coastguard Worker  if (static_cast<size_t>(CharCount) == ResultPath.capacity()) {
653*9880d681SAndroid Build Coastguard Worker    // Use lstat to get the size of the filename
654*9880d681SAndroid Build Coastguard Worker    struct stat sb;
655*9880d681SAndroid Build Coastguard Worker    if (::lstat(ProcPath, &sb) < 0)
656*9880d681SAndroid Build Coastguard Worker      return std::error_code(errno, std::generic_category());
657*9880d681SAndroid Build Coastguard Worker
658*9880d681SAndroid Build Coastguard Worker    ResultPath.reserve(sb.st_size + 1);
659*9880d681SAndroid Build Coastguard Worker    CharCount = ::readlink(ProcPath, ResultPath.begin(), ResultPath.capacity());
660*9880d681SAndroid Build Coastguard Worker    if (CharCount < 0)
661*9880d681SAndroid Build Coastguard Worker      return std::error_code(errno, std::generic_category());
662*9880d681SAndroid Build Coastguard Worker
663*9880d681SAndroid Build Coastguard Worker    // Test for race condition: did the link size change?
664*9880d681SAndroid Build Coastguard Worker    if (CharCount > sb.st_size)
665*9880d681SAndroid Build Coastguard Worker      return std::error_code(ENAMETOOLONG, std::generic_category());
666*9880d681SAndroid Build Coastguard Worker  }
667*9880d681SAndroid Build Coastguard Worker  ResultPath.set_size(static_cast<size_t>(CharCount));
668*9880d681SAndroid Build Coastguard Worker#endif
669*9880d681SAndroid Build Coastguard Worker  return std::error_code();
670*9880d681SAndroid Build Coastguard Worker}
671*9880d681SAndroid Build Coastguard Worker
672*9880d681SAndroid Build Coastguard Worker} // end namespace fs
673*9880d681SAndroid Build Coastguard Worker
674*9880d681SAndroid Build Coastguard Workernamespace path {
675*9880d681SAndroid Build Coastguard Worker
676*9880d681SAndroid Build Coastguard Workerbool home_directory(SmallVectorImpl<char> &result) {
677*9880d681SAndroid Build Coastguard Worker  if (char *RequestedDir = getenv("HOME")) {
678*9880d681SAndroid Build Coastguard Worker    result.clear();
679*9880d681SAndroid Build Coastguard Worker    result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
680*9880d681SAndroid Build Coastguard Worker    return true;
681*9880d681SAndroid Build Coastguard Worker  }
682*9880d681SAndroid Build Coastguard Worker
683*9880d681SAndroid Build Coastguard Worker  return false;
684*9880d681SAndroid Build Coastguard Worker}
685*9880d681SAndroid Build Coastguard Worker
686*9880d681SAndroid Build Coastguard Workerstatic bool getDarwinConfDir(bool TempDir, SmallVectorImpl<char> &Result) {
687*9880d681SAndroid Build Coastguard Worker  #if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR)
688*9880d681SAndroid Build Coastguard Worker  // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR.
689*9880d681SAndroid Build Coastguard Worker  // macros defined in <unistd.h> on darwin >= 9
690*9880d681SAndroid Build Coastguard Worker  int ConfName = TempDir ? _CS_DARWIN_USER_TEMP_DIR
691*9880d681SAndroid Build Coastguard Worker                         : _CS_DARWIN_USER_CACHE_DIR;
692*9880d681SAndroid Build Coastguard Worker  size_t ConfLen = confstr(ConfName, nullptr, 0);
693*9880d681SAndroid Build Coastguard Worker  if (ConfLen > 0) {
694*9880d681SAndroid Build Coastguard Worker    do {
695*9880d681SAndroid Build Coastguard Worker      Result.resize(ConfLen);
696*9880d681SAndroid Build Coastguard Worker      ConfLen = confstr(ConfName, Result.data(), Result.size());
697*9880d681SAndroid Build Coastguard Worker    } while (ConfLen > 0 && ConfLen != Result.size());
698*9880d681SAndroid Build Coastguard Worker
699*9880d681SAndroid Build Coastguard Worker    if (ConfLen > 0) {
700*9880d681SAndroid Build Coastguard Worker      assert(Result.back() == 0);
701*9880d681SAndroid Build Coastguard Worker      Result.pop_back();
702*9880d681SAndroid Build Coastguard Worker      return true;
703*9880d681SAndroid Build Coastguard Worker    }
704*9880d681SAndroid Build Coastguard Worker
705*9880d681SAndroid Build Coastguard Worker    Result.clear();
706*9880d681SAndroid Build Coastguard Worker  }
707*9880d681SAndroid Build Coastguard Worker  #endif
708*9880d681SAndroid Build Coastguard Worker  return false;
709*9880d681SAndroid Build Coastguard Worker}
710*9880d681SAndroid Build Coastguard Worker
711*9880d681SAndroid Build Coastguard Workerstatic bool getUserCacheDir(SmallVectorImpl<char> &Result) {
712*9880d681SAndroid Build Coastguard Worker  // First try using XDG_CACHE_HOME env variable,
713*9880d681SAndroid Build Coastguard Worker  // as specified in XDG Base Directory Specification at
714*9880d681SAndroid Build Coastguard Worker  // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
715*9880d681SAndroid Build Coastguard Worker  if (const char *XdgCacheDir = std::getenv("XDG_CACHE_HOME")) {
716*9880d681SAndroid Build Coastguard Worker    Result.clear();
717*9880d681SAndroid Build Coastguard Worker    Result.append(XdgCacheDir, XdgCacheDir + strlen(XdgCacheDir));
718*9880d681SAndroid Build Coastguard Worker    return true;
719*9880d681SAndroid Build Coastguard Worker  }
720*9880d681SAndroid Build Coastguard Worker
721*9880d681SAndroid Build Coastguard Worker  // Try Darwin configuration query
722*9880d681SAndroid Build Coastguard Worker  if (getDarwinConfDir(false, Result))
723*9880d681SAndroid Build Coastguard Worker    return true;
724*9880d681SAndroid Build Coastguard Worker
725*9880d681SAndroid Build Coastguard Worker  // Use "$HOME/.cache" if $HOME is available
726*9880d681SAndroid Build Coastguard Worker  if (home_directory(Result)) {
727*9880d681SAndroid Build Coastguard Worker    append(Result, ".cache");
728*9880d681SAndroid Build Coastguard Worker    return true;
729*9880d681SAndroid Build Coastguard Worker  }
730*9880d681SAndroid Build Coastguard Worker
731*9880d681SAndroid Build Coastguard Worker  return false;
732*9880d681SAndroid Build Coastguard Worker}
733*9880d681SAndroid Build Coastguard Worker
734*9880d681SAndroid Build Coastguard Workerstatic const char *getEnvTempDir() {
735*9880d681SAndroid Build Coastguard Worker  // Check whether the temporary directory is specified by an environment
736*9880d681SAndroid Build Coastguard Worker  // variable.
737*9880d681SAndroid Build Coastguard Worker  const char *EnvironmentVariables[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"};
738*9880d681SAndroid Build Coastguard Worker  for (const char *Env : EnvironmentVariables) {
739*9880d681SAndroid Build Coastguard Worker    if (const char *Dir = std::getenv(Env))
740*9880d681SAndroid Build Coastguard Worker      return Dir;
741*9880d681SAndroid Build Coastguard Worker  }
742*9880d681SAndroid Build Coastguard Worker
743*9880d681SAndroid Build Coastguard Worker  return nullptr;
744*9880d681SAndroid Build Coastguard Worker}
745*9880d681SAndroid Build Coastguard Worker
746*9880d681SAndroid Build Coastguard Workerstatic const char *getDefaultTempDir(bool ErasedOnReboot) {
747*9880d681SAndroid Build Coastguard Worker#ifdef P_tmpdir
748*9880d681SAndroid Build Coastguard Worker  if ((bool)P_tmpdir)
749*9880d681SAndroid Build Coastguard Worker    return P_tmpdir;
750*9880d681SAndroid Build Coastguard Worker#endif
751*9880d681SAndroid Build Coastguard Worker
752*9880d681SAndroid Build Coastguard Worker  if (ErasedOnReboot)
753*9880d681SAndroid Build Coastguard Worker    return "/tmp";
754*9880d681SAndroid Build Coastguard Worker  return "/var/tmp";
755*9880d681SAndroid Build Coastguard Worker}
756*9880d681SAndroid Build Coastguard Worker
757*9880d681SAndroid Build Coastguard Workervoid system_temp_directory(bool ErasedOnReboot, SmallVectorImpl<char> &Result) {
758*9880d681SAndroid Build Coastguard Worker  Result.clear();
759*9880d681SAndroid Build Coastguard Worker
760*9880d681SAndroid Build Coastguard Worker  if (ErasedOnReboot) {
761*9880d681SAndroid Build Coastguard Worker    // There is no env variable for the cache directory.
762*9880d681SAndroid Build Coastguard Worker    if (const char *RequestedDir = getEnvTempDir()) {
763*9880d681SAndroid Build Coastguard Worker      Result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
764*9880d681SAndroid Build Coastguard Worker      return;
765*9880d681SAndroid Build Coastguard Worker    }
766*9880d681SAndroid Build Coastguard Worker  }
767*9880d681SAndroid Build Coastguard Worker
768*9880d681SAndroid Build Coastguard Worker  if (getDarwinConfDir(ErasedOnReboot, Result))
769*9880d681SAndroid Build Coastguard Worker    return;
770*9880d681SAndroid Build Coastguard Worker
771*9880d681SAndroid Build Coastguard Worker  const char *RequestedDir = getDefaultTempDir(ErasedOnReboot);
772*9880d681SAndroid Build Coastguard Worker  Result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
773*9880d681SAndroid Build Coastguard Worker}
774*9880d681SAndroid Build Coastguard Worker
775*9880d681SAndroid Build Coastguard Worker} // end namespace path
776*9880d681SAndroid Build Coastguard Worker
777*9880d681SAndroid Build Coastguard Worker} // end namespace sys
778*9880d681SAndroid Build Coastguard Worker} // end namespace llvm
779