summaryrefslogtreecommitdiff
path: root/llvm/lib/Support/Unix/Path.inc
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support/Unix/Path.inc')
-rw-r--r--llvm/lib/Support/Unix/Path.inc111
1 files changed, 88 insertions, 23 deletions
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index 2a03dc682bced..d91b269cc6d33 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -48,6 +48,8 @@ extern char **environ;
#endif
#elif defined(__DragonFly__)
#include <sys/mount.h>
+#elif defined(__MVS__)
+#include <sys/ps.h>
#endif
// Both stdio.h and cstdio are included via different paths and
@@ -56,10 +58,13 @@ extern char **environ;
#undef ferror
#undef feof
+#if !defined(PATH_MAX)
// For GNU Hurd
-#if defined(__GNU__) && !defined(PATH_MAX)
-# define PATH_MAX 4096
-# define MAXPATHLEN 4096
+#if defined(__GNU__)
+#define PATH_MAX 4096
+#elif defined(__MVS__)
+#define PATH_MAX _XOPEN_PATH_MAX
+#endif
#endif
#include <sys/types.h>
@@ -101,7 +106,8 @@ typedef uint_t uint;
#define STATVFS_F_FRSIZE(vfs) static_cast<uint64_t>(vfs.f_bsize)
#endif
-#if defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__)
+#if defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__) || \
+ defined(__MVS__)
#define STATVFS_F_FLAG(vfs) (vfs).f_flag
#else
#define STATVFS_F_FLAG(vfs) (vfs).f_flags
@@ -184,10 +190,10 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
// On OS X the executable path is saved to the stack by dyld. Reading it
// from there is much faster than calling dladdr, especially for large
// binaries with symbols.
- char exe_path[MAXPATHLEN];
+ char exe_path[PATH_MAX];
uint32_t size = sizeof(exe_path);
if (_NSGetExecutablePath(exe_path, &size) == 0) {
- char link_path[MAXPATHLEN];
+ char link_path[PATH_MAX];
if (realpath(exe_path, link_path))
return link_path;
}
@@ -208,14 +214,9 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
while (*p++ != 0)
;
// Iterate through auxiliary vectors for AT_EXECPATH.
- for (;;) {
- switch (*(uintptr_t *)p++) {
- case AT_EXECPATH:
+ for (; *(uintptr_t *)p != AT_NULL; p++) {
+ if (*(uintptr_t *)p++ == AT_EXECPATH)
return *p;
- case AT_NULL:
- break;
- }
- p++;
}
#endif
// Fall back to argv[0] if auxiliary vectors are not available.
@@ -239,7 +240,7 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
if (getprogpath(exe_path, argv0) != NULL)
return exe_path;
#elif defined(__linux__) || defined(__CYGWIN__) || defined(__gnu_hurd__)
- char exe_path[MAXPATHLEN];
+ char exe_path[PATH_MAX];
const char *aPath = "/proc/self/exe";
if (sys::fs::exists(aPath)) {
// /proc is not always mounted under Linux (chroot for example).
@@ -263,7 +264,7 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
return ret;
}
#else
- char real_path[MAXPATHLEN];
+ char real_path[PATH_MAX];
if (realpath(exe_path, real_path))
return std::string(real_path);
#endif
@@ -271,6 +272,26 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
// Fall back to the classical detection.
if (getprogpath(exe_path, argv0))
return exe_path;
+#elif defined(__MVS__)
+ int token = 0;
+ W_PSPROC buf;
+ char exe_path[PS_PATHBLEN];
+ pid_t pid = getpid();
+
+ memset(&buf, 0, sizeof(buf));
+ buf.ps_pathptr = exe_path;
+ buf.ps_pathlen = sizeof(exe_path);
+
+ while (true) {
+ if ((token = w_getpsent(token, &buf, sizeof(buf))) <= 0)
+ break;
+ if (buf.ps_pid != pid)
+ continue;
+ char real_path[PATH_MAX];
+ if (realpath(exe_path, real_path))
+ return std::string(real_path);
+ break; // Found entry, but realpath failed.
+ }
#elif defined(HAVE_DLFCN_H) && defined(HAVE_DLADDR)
// Use dladdr to get executable path if available.
Dl_info DLInfo;
@@ -280,7 +301,7 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
// If the filename is a symlink, we need to resolve and return the location of
// the actual executable.
- char link_path[MAXPATHLEN];
+ char link_path[PATH_MAX];
if (realpath(DLInfo.dli_fname, link_path))
return link_path;
#else
@@ -330,12 +351,7 @@ std::error_code current_path(SmallVectorImpl<char> &result) {
return std::error_code();
}
-#ifdef MAXPATHLEN
- result.reserve(MAXPATHLEN);
-#else
-// For GNU Hurd
- result.reserve(1024);
-#endif
+ result.reserve(PATH_MAX);
while (true) {
if (::getcwd(result.data(), result.capacity()) == nullptr) {
@@ -504,6 +520,10 @@ static bool is_local_impl(struct STATVFS &Vfs) {
// vmount entry not found; "remote" is the conservative answer.
return false;
+#elif defined(__MVS__)
+ // The file system can have an arbitrary structure on z/OS; must go with the
+ // conservative answer.
+ return false;
#else
return !!(STATVFS_F_FLAG(Vfs) & MNT_LOCAL);
#endif
@@ -998,7 +1018,7 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD,
#if defined(F_GETPATH)
// When F_GETPATH is availble, it is the quickest way to get
// the real path name.
- char Buffer[MAXPATHLEN];
+ char Buffer[PATH_MAX];
if (::fcntl(ResultFD, F_GETPATH, Buffer) != -1)
RealPath->append(Buffer, Buffer + strlen(Buffer));
#else
@@ -1169,6 +1189,51 @@ static bool getDarwinConfDir(bool TempDir, SmallVectorImpl<char> &Result) {
return false;
}
+bool user_config_directory(SmallVectorImpl<char> &result) {
+#ifdef __APPLE__
+ // Mac: ~/Library/Preferences/
+ if (home_directory(result)) {
+ append(result, "Library", "Preferences");
+ return true;
+ }
+#else
+ // XDG_CONFIG_HOME as defined in the XDG Base Directory Specification:
+ // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+ if (const char *RequestedDir = getenv("XDG_CONFIG_HOME")) {
+ result.clear();
+ result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
+ return true;
+ }
+#endif
+ // Fallback: ~/.config
+ if (!home_directory(result)) {
+ return false;
+ }
+ append(result, ".config");
+ return true;
+}
+
+bool cache_directory(SmallVectorImpl<char> &result) {
+#ifdef __APPLE__
+ if (getDarwinConfDir(false/*tempDir*/, result)) {
+ return true;
+ }
+#else
+ // XDG_CACHE_HOME as defined in the XDG Base Directory Specification:
+ // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+ if (const char *RequestedDir = getenv("XDG_CACHE_HOME")) {
+ result.clear();
+ result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
+ return true;
+ }
+#endif
+ if (!home_directory(result)) {
+ return false;
+ }
+ append(result, ".cache");
+ return true;
+}
+
static const char *getEnvTempDir() {
// Check whether the temporary directory is specified by an environment
// variable.