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.
This commit is contained in:
parent
0db25a91f0
commit
71801576eb
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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_ */
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user