diff options
Diffstat (limited to 'llvm/lib/Support/Unix/Path.inc')
-rw-r--r-- | llvm/lib/Support/Unix/Path.inc | 111 |
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. |