From 71801576eb58da81ed4b9b0c607a36a7f6dd8200 Mon Sep 17 00:00:00 2001 From: mischief Date: Wed, 4 Feb 2026 00:03:03 -0800 Subject: [PATCH] unix: make OpenBSD uv_exepath work some users of libuv rely on uv_exepath to be an actual path to a program. unfortunately, the OpenBSD KERN_PROC_ARGV sysctl just returns what is in argv[0], so if the program was executed by being looked up in $PATH, uv_exepath would only return the basename and not an actual path. to fix, this use the same approach as IBM i, OS/390 and AIX by searching with uv__search_path. this is also the same approach the Zig language has taken for the similar selfExePath function for OpenBSD. the tests expect that uv_exepath still works after uv_set_process_title, which on BSD is a call to setproctitle. the place setproctitle stores to is the same place that KERN_PROC_ARGV reads from, so we need to stash the original argv[0] in uv_setup_args to recover it later in uv_exepath. --- src/unix/bsd-proctitle.c | 3 ++- src/unix/internal.h | 2 ++ src/unix/openbsd.c | 47 +++----------------------------------- test/test-get-currentexe.c | 3 --- 4 files changed, 7 insertions(+), 48 deletions(-) diff --git a/src/unix/bsd-proctitle.c b/src/unix/bsd-proctitle.c index b0c01e2cb..761603995 100644 --- a/src/unix/bsd-proctitle.c +++ b/src/unix/bsd-proctitle.c @@ -29,7 +29,7 @@ static uv_mutex_t process_title_mutex; static uv_once_t process_title_mutex_once = UV_ONCE_INIT; static char* process_title; - +char* uv_saved_argv0; static void init_process_title_mutex_once(void) { if (uv_mutex_init(&process_title_mutex)) @@ -45,6 +45,7 @@ void uv__process_title_cleanup(void) { char** uv_setup_args(int argc, char** argv) { process_title = argc > 0 ? uv__strdup(argv[0]) : NULL; + uv_saved_argv0 = argc > 0 ? uv__strdup(argv[0]) : NULL; return argv; } diff --git a/src/unix/internal.h b/src/unix/internal.h index d17c7cbb9..6359694c2 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h @@ -591,4 +591,6 @@ int uv__get_constrained_cpu(long long* quota); #define UV__KQUEUE_EVFILT_USER 0 #endif +extern char* uv_saved_argv0; + #endif /* UV_UNIX_INTERNAL_H_ */ diff --git a/src/unix/openbsd.c b/src/unix/openbsd.c index cf20fa665..a6d58b948 100644 --- a/src/unix/openbsd.c +++ b/src/unix/openbsd.c @@ -59,54 +59,13 @@ void uv_loadavg(double avg[3]) { int uv_exepath(char* buffer, size_t* size) { - int mib[4]; - char **argsbuf = NULL; - size_t argsbuf_size = 100U; - size_t exepath_size; - pid_t mypid; - int err; - if (buffer == NULL || size == NULL || *size == 0) return UV_EINVAL; - mypid = getpid(); - for (;;) { - err = UV_ENOMEM; - argsbuf = uv__reallocf(argsbuf, argsbuf_size); - if (argsbuf == NULL) - goto out; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC_ARGS; - mib[2] = mypid; - mib[3] = KERN_PROC_ARGV; - if (sysctl(mib, ARRAY_SIZE(mib), argsbuf, &argsbuf_size, NULL, 0) == 0) { - break; - } - if (errno != ENOMEM) { - err = UV__ERR(errno); - goto out; - } - argsbuf_size *= 2U; - } + if (uv_saved_argv0 == NULL) + return UV_EINVAL; - if (argsbuf[0] == NULL) { - err = UV_EINVAL; /* FIXME(bnoordhuis) More appropriate error. */ - goto out; - } - - *size -= 1; - exepath_size = strlen(argsbuf[0]); - if (*size > exepath_size) - *size = exepath_size; - - memcpy(buffer, argsbuf[0], *size); - buffer[*size] = '\0'; - err = 0; - -out: - uv__free(argsbuf); - - return err; + return uv__search_path(uv_saved_argv0, buffer, size); } diff --git a/test/test-get-currentexe.c b/test/test-get-currentexe.c index c813d3a5c..98acbfd99 100644 --- a/test/test-get-currentexe.c +++ b/test/test-get-currentexe.c @@ -35,9 +35,6 @@ TEST_IMPL(get_currentexe) { #if defined(__QEMU__) RETURN_SKIP("Test does not currently work in QEMU"); #endif -#if defined(__OpenBSD__) - RETURN_SKIP("Test does not currently work in OpenBSD"); -#endif char buffer[PATHMAX]; char path[PATHMAX];