From bfd84b1c034d6b0413c293772662e1a5619d6b40 Mon Sep 17 00:00:00 2001 From: Kai Nacke Date: Mon, 6 Jul 2020 05:53:29 -0400 Subject: [PATCH] [SystemZ/ZOS] Implement getMainExecutable() and is_local_impl() Adds implementation of getMainExecutable() and is_local_impl() to Support/Unix/Path.inc. Both are needed to compile LLVM for z/OS. Reviewed By: hubert.reinterpretcast, emaste Differential Revision: https://reviews.llvm.org/D82544 --- llvm/lib/Support/Unix/Path.inc | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc index 824e8b0..c35db79 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 +#elif defined(__MVS__) +#include #endif // Both stdio.h and cstdio are included via different paths and @@ -56,9 +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 +#if defined(__GNU__) +#define PATH_MAX 4096 +#elif defined(__MVS__) +#define PATH_MAX _XOPEN_PATH_MAX +#endif #endif #include @@ -100,7 +106,8 @@ typedef uint_t uint; #define STATVFS_F_FRSIZE(vfs) static_cast(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 @@ -265,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; @@ -493,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 -- 2.7.4