From ce3b418d16553191806e6387553e113569b16cd7 Mon Sep 17 00:00:00 2001 From: Toby Lane Date: Wed, 27 Apr 2022 17:38:19 +0100 Subject: [PATCH] Update whereami --- libs/whereami/whereami.c | 174 ++++++++++++++++++++++++++++++++------- 1 file changed, 144 insertions(+), 30 deletions(-) diff --git a/libs/whereami/whereami.c b/libs/whereami/whereami.c index 11f4ac6b0..c06e98c9a 100644 --- a/libs/whereami/whereami.c +++ b/libs/whereami/whereami.c @@ -12,6 +12,15 @@ extern "C" { #endif +#if defined(__linux__) || defined(__CYGWIN__) +#undef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE +#elif defined(__APPLE__) +#undef _DARWIN_C_SOURCE +#define _DARWIN_C_SOURCE +#define _DARWIN_BETTER_REALPATH +#endif + #if !defined(WAI_MALLOC) || !defined(WAI_FREE) || !defined(WAI_REALLOC) #include #endif @@ -59,6 +68,7 @@ extern "C" { #if defined(_MSC_VER) #pragma warning(pop) #endif +#include static int WAI_PREFIX(getModulePath_)(HMODULE module, char* out, int capacity, int* dirname_length) { @@ -66,8 +76,9 @@ static int WAI_PREFIX(getModulePath_)(HMODULE module, char* out, int capacity, i wchar_t buffer2[MAX_PATH]; wchar_t* path = NULL; int length = -1; + bool ok; - for (;;) + for (ok = false; !ok; ok = true) { DWORD size; int length_, length__; @@ -123,14 +134,12 @@ static int WAI_PREFIX(getModulePath_)(HMODULE module, char* out, int capacity, i } length = length__; - - break; } if (path != buffer1) WAI_FREE(path); - return length; + return ok ? length : -1; } WAI_NOINLINE WAI_FUNCSPEC @@ -174,6 +183,7 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) #define __STDC_FORMAT_MACROS #endif #include +#include #if !defined(WAI_PROC_SELF_EXE) #if defined(__sun) @@ -189,8 +199,9 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) char buffer[PATH_MAX]; char* resolved = NULL; int length = -1; + bool ok; - for (;;) + for (ok = false; !ok; ok = true) { resolved = realpath(WAI_PROC_SELF_EXE, buffer); if (!resolved) @@ -215,11 +226,9 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) } } } - - break; } - return length; + return ok ? length : -1; } #if !defined(WAI_PROC_SELF_MAPS_RETRY) @@ -239,6 +248,7 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) #include #include #endif +#include WAI_NOINLINE WAI_FUNCSPEC int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) @@ -354,20 +364,17 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) break; } - if (maps) - fclose(maps); - return length; } #elif defined(__APPLE__) -#define _DARWIN_BETTER_REALPATH #include #include #include #include #include +#include WAI_FUNCSPEC int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) @@ -377,8 +384,9 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) char* path = buffer1; char* resolved = NULL; int length = -1; + bool ok; - for (;;) + for (ok = false; !ok; ok = true) { uint32_t size = (uint32_t)sizeof(buffer1); if (_NSGetExecutablePath(path, &size) == -1) @@ -411,14 +419,12 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) } } } - - break; } if (path != buffer1) WAI_FREE(path); - return length; + return ok ? length : -1; } WAI_NOINLINE WAI_FUNCSPEC @@ -472,6 +478,7 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) #include #include #include +#include #if !defined(WAI_PROC_SELF_EXE) #define WAI_PROC_SELF_EXE "/proc/self/exefile" @@ -485,8 +492,9 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) char* resolved = NULL; FILE* self_exe = NULL; int length = -1; + bool ok; - for (;;) + for (ok = false; !ok; ok = true) { self_exe = fopen(WAI_PROC_SELF_EXE, "r"); if (!self_exe) @@ -518,13 +526,11 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) } } } - - break; } fclose(self_exe); - return length; + return ok ? length : -1; } WAI_FUNCSPEC @@ -572,7 +578,7 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) } #elif defined(__DragonFly__) || defined(__FreeBSD__) || \ - defined(__FreeBSD_kernel__) || defined(__NetBSD__) + defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) #include #include @@ -580,6 +586,116 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) #include #include #include +#include + +#if defined(__OpenBSD__) + +#include + +WAI_FUNCSPEC +int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) +{ + char buffer1[4096]; + char buffer2[PATH_MAX]; + char buffer3[PATH_MAX]; + char** argv = (char**)buffer1; + char* resolved = NULL; + int length = -1; + bool ok; + + for (ok = false; !ok; ok = true) + { + int mib[4] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV }; + size_t size; + + if (sysctl(mib, 4, NULL, &size, NULL, 0) != 0) + break; + + if (size > sizeof(buffer1)) + { + argv = (char**)WAI_MALLOC(size); + if (!argv) + break; + } + + if (sysctl(mib, 4, argv, &size, NULL, 0) != 0) + break; + + if (strchr(argv[0], '/')) + { + resolved = realpath(argv[0], buffer2); + if (!resolved) + break; + } + else + { + const char* PATH = getenv("PATH"); + if (!PATH) + break; + + size_t argv0_length = strlen(argv[0]); + + const char* begin = PATH; + while (1) + { + const char* separator = strchr(begin, ':'); + const char* end = separator ? separator : begin + strlen(begin); + + if (end - begin > 0) + { + if (*(end -1) == '/') + --end; + + if (((end - begin) + 1 + argv0_length + 1) <= sizeof(buffer2)) + { + memcpy(buffer2, begin, end - begin); + buffer2[end - begin] = '/'; + memcpy(buffer2 + (end - begin) + 1, argv[0], argv0_length + 1); + + resolved = realpath(buffer2, buffer3); + if (resolved) + break; + } + } + + if (!separator) + break; + + begin = ++separator; + } + + if (!resolved) + break; + } + + length = (int)strlen(resolved); + if (length <= capacity) + { + memcpy(out, resolved, length); + + if (dirname_length) + { + int i; + + for (i = length - 1; i >= 0; --i) + { + if (out[i] == '/') + { + *dirname_length = i; + break; + } + } + } + } + } + + if (argv != (char**)buffer1) + WAI_FREE(argv); + + return ok ? length : -1; +} + +#else WAI_FUNCSPEC int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) @@ -589,8 +705,9 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) char* path = buffer1; char* resolved = NULL; int length = -1; + bool ok; - for (;;) + for (ok = false; !ok; ok = true) { #if defined(__NetBSD__) int mib[4] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME }; @@ -599,7 +716,7 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) #endif size_t size = sizeof(buffer1); - if (sysctl(mib, (u_int)(sizeof(mib) / sizeof(mib[0])), path, &size, NULL, 0) != 0) + if (sysctl(mib, 4, path, &size, NULL, 0) != 0) break; resolved = realpath(path, buffer2); @@ -625,16 +742,13 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) } } } - - break; } - if (path != buffer1) - WAI_FREE(path); - - return length; + return ok ? length : -1; } +#endif + WAI_NOINLINE WAI_FUNCSPEC int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) { @@ -687,4 +801,4 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) #ifdef __cplusplus } -#endif +#endif \ No newline at end of file