From e1524ae3ee64b2670e115ec26bd92a3fdab3d6fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20P=C3=B6chtrager?= Date: Sun, 19 Jul 2015 20:25:53 +0200 Subject: [PATCH] use a different method to get the executable path on openbsd --- cctools/ld64/src/3rd/helper.c | 70 +++++++++++++---- cctools/libstuff/emulated.c | 102 +++++++++++++++++-------- usage_examples/ios_toolchain/wrapper.c | 75 ++++++++++++++---- 3 files changed, 190 insertions(+), 57 deletions(-) diff --git a/cctools/ld64/src/3rd/helper.c b/cctools/ld64/src/3rd/helper.c index 2bed7244..199990a4 100644 --- a/cctools/ld64/src/3rd/helper.c +++ b/cctools/ld64/src/3rd/helper.c @@ -17,11 +17,17 @@ const char ldVersionString[] = "242\n"; #include #include #include - -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) #include #endif +#ifdef __OpenBSD__ +#include +#include +#include +#endif + #include "helper.h" void __assert_rtn(const char *func, const char *file, int line, const char *msg) @@ -36,39 +42,75 @@ void __assert_rtn(const char *func, const char *file, int line, const char *msg) } -int _NSGetExecutablePath(char *path, unsigned int *size) +int _NSGetExecutablePath(char *epath, unsigned int *size) { #ifdef __FreeBSD__ int mib[4]; - mib[0] = CTL_KERN; + mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PATHNAME; mib[3] = -1; size_t cb = *size; - if (sysctl(mib, 4, path, &cb, NULL, 0) != 0) + if (sysctl(mib, 4, epath, &cb, NULL, 0) != 0) return -1; *size = cb; - return 0; + return 0; #elif defined(__OpenBSD__) int mib[4]; - const char *tmp[100]; - size_t l = sizeof(tmp); + char **argv; + size_t len; + const char *comm; + int ok = 0; mib[0] = CTL_KERN; mib[1] = KERN_PROC_ARGS; mib[2] = getpid(); mib[3] = KERN_PROC_ARGV; - if (sysctl(mib, 4, tmp, &l, NULL, 0) != 0) - return -1; - *size = strlcpy(path, tmp[0], *size); - return 0; + if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) + abort(); + if (!(argv = malloc(len))) + abort(); + if (sysctl(mib, 4, argv, &len, NULL, 0) < 0) + abort(); + comm = argv[0]; + if (*comm == '/' || *comm == '.') { + char *rpath; + if ((rpath = realpath(comm, NULL))) { + snprintf(epath, *size, "%s", rpath); + free(rpath); + ok = 1; + } + } else { + char *sp; + char *xpath = strdup(getenv("PATH")); + char *path = strtok_r(xpath, ":", &sp); + struct stat st; + if (!xpath) + abort(); + while (path) { + snprintf(epath, *size, "%s/%s", path, comm); + if (!stat(epath, &st) && (st.st_mode & S_IXUSR)) { + ok = 1; + break; + } + path = strtok_r(NULL, ":", &sp); + } + free(xpath); + } + free(argv); + if (ok) { + *strrchr(epath, '/') = '\0'; + *size = strlen(epath); + return 0; + } + return -1; #else int bufsize = *size; int ret_size; - ret_size = readlink("/proc/self/exe", path, bufsize-1); + ret_size = readlink("/proc/self/exe", epath, bufsize-1); if (ret_size != -1) { *size = ret_size; - path[ret_size]=0; + epath[ret_size]=0; return 0; } else diff --git a/cctools/libstuff/emulated.c b/cctools/libstuff/emulated.c index 1aa355ca..aa72142e 100644 --- a/cctools/libstuff/emulated.c +++ b/cctools/libstuff/emulated.c @@ -14,46 +14,88 @@ #include #include -#if defined(__FreeBSD__) || defined(__OpenBSD__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) #include #endif -int _NSGetExecutablePath(char *path, unsigned int *size) +#ifdef __OpenBSD__ +#include +#include +#include +#endif + +int _NSGetExecutablePath(char *epath, unsigned int *size) { #ifdef __FreeBSD__ - int mib[4]; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - mib[3] = -1; - size_t cb = *size; - if (sysctl(mib, 4, path, &cb, NULL, 0) != 0) + int mib[4]; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PATHNAME; + mib[3] = -1; + size_t cb = *size; + if (sysctl(mib, 4, epath, &cb, NULL, 0) != 0) return -1; - *size = cb; - return 0; + *size = cb; + return 0; #elif defined(__OpenBSD__) - int mib[4]; - const char *tmp[100]; - size_t l = sizeof(tmp); - mib[0] = CTL_KERN; - mib[1] = KERN_PROC_ARGS; - mib[2] = getpid(); - mib[3] = KERN_PROC_ARGV; - if (sysctl(mib, 4, tmp, &l, NULL, 0) != 0) - return -1; - *size = strlcpy(path, tmp[0], *size); - return 0; + int mib[4]; + char **argv; + size_t len; + const char *comm; + int ok = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC_ARGS; + mib[2] = getpid(); + mib[3] = KERN_PROC_ARGV; + if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) + abort(); + if (!(argv = malloc(len))) + abort(); + if (sysctl(mib, 4, argv, &len, NULL, 0) < 0) + abort(); + comm = argv[0]; + if (*comm == '/' || *comm == '.') { + char *rpath; + if ((rpath = realpath(comm, NULL))) { + snprintf(epath, *size, "%s", rpath); + free(rpath); + ok = 1; + } + } else { + char *sp; + char *xpath = strdup(getenv("PATH")); + char *path = strtok_r(xpath, ":", &sp); + struct stat st; + if (!xpath) + abort(); + while (path) { + snprintf(epath, *size, "%s/%s", path, comm); + if (!stat(epath, &st) && (st.st_mode & S_IXUSR)) { + ok = 1; + break; + } + path = strtok_r(NULL, ":", &sp); + } + free(xpath); + } + free(argv); + if (ok) { + *strrchr(epath, '/') = '\0'; + *size = strlen(epath); + return 0; + } + return -1; #else - int bufsize = *size; - int ret_size; - ret_size = readlink("/proc/self/exe", path, bufsize-1); - if (ret_size != -1) - { + int bufsize = *size; + int ret_size; + ret_size = readlink("/proc/self/exe", epath, bufsize-1); + if (ret_size != -1) + { *size = ret_size; - path[ret_size]=0; + epath[ret_size]=0; return 0; - } - else + } + else return -1; #endif } diff --git a/usage_examples/ios_toolchain/wrapper.c b/usage_examples/ios_toolchain/wrapper.c index a55bd412..3871fbb0 100644 --- a/usage_examples/ios_toolchain/wrapper.c +++ b/usage_examples/ios_toolchain/wrapper.c @@ -19,30 +19,79 @@ #include #endif -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) #include #endif -char *get_executable_path(char *buf, size_t len) +#ifdef __OpenBSD__ +#include +#include +#include +#endif + +char *get_executable_path(char *epath, size_t buflen) { char *p; #ifdef __APPLE__ - unsigned int l = len; - if (_NSGetExecutablePath(buf, &l) != 0) return NULL; + unsigned int l = buflen; + if (_NSGetExecutablePath(epath, &l) != 0) return NULL; #elif defined(__FreeBSD__) int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; - size_t l = len; - if (sysctl(mib, 4, buf, &l, NULL, 0) != 0) return NULL; -#elif defined(_WIN32) - size_t l = GetModuleFileName(NULL, buf, (DWORD)len); + size_t l = buflen; + if (sysctl(mib, 4, epath, &l, NULL, 0) != 0) return NULL; +#elif defined(__OpenBSD__) + int mib[4]; + char **argv; + size_t len; + size_t l; + const char *comm; + int ok = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC_ARGS; + mib[2] = getpid(); + mib[3] = KERN_PROC_ARGV; + if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) + abort(); + if (!(argv = malloc(len))) + abort(); + if (sysctl(mib, 4, argv, &len, NULL, 0) < 0) + abort(); + comm = argv[0]; + if (*comm == '/' || *comm == '.') { + char *rpath; + if ((rpath = realpath(comm, NULL))) { + snprintf(epath, buflen, "%s", rpath); + free(rpath); + ok = 1; + } + } else { + char *sp; + char *xpath = strdup(getenv("PATH")); + char *path = strtok_r(xpath, ":", &sp); + struct stat st; + if (!xpath) + abort(); + while (path) { + snprintf(epath, buflen, "%s/%s", path, comm); + if (!stat(epath, &st) && (st.st_mode & S_IXUSR)) { + ok = 1; + break; + } + path = strtok_r(NULL, ":", &sp); + } + free(xpath); + } + free(argv); + if (!ok) return NULL; + l = strlen(epath); #else - ssize_t l = readlink("/proc/self/exe", buf, len); + ssize_t l = readlink("/proc/self/exe", epath, buflen); #endif if (l <= 0) return NULL; - buf[len - 1] = '\0'; - p = strrchr(buf, '/'); + epath[buflen - 1] = '\0'; + p = strrchr(epath, '/'); if (p) *p = '\0'; - return buf; + return epath; } char *get_filename(char *str) @@ -88,7 +137,7 @@ int main(int argc, char *argv[]) target_info(argv, &target, &compiler); if (!get_executable_path(execpath, sizeof(execpath))) abort(); snprintf(sdkpath, sizeof(sdkpath), "%s/../SDK", execpath); - + snprintf(codesign_allocate, sizeof(codesign_allocate), "%s-codesign_allocate", target);