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
fc90bb9843
commit
2b7d4a05a2
@ -29,7 +29,7 @@
|
|||||||
static uv_mutex_t process_title_mutex;
|
static uv_mutex_t process_title_mutex;
|
||||||
static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
|
static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
|
||||||
static char* process_title;
|
static char* process_title;
|
||||||
|
char* uv_saved_argv0;
|
||||||
|
|
||||||
static void init_process_title_mutex_once(void) {
|
static void init_process_title_mutex_once(void) {
|
||||||
if (uv_mutex_init(&process_title_mutex))
|
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) {
|
char** uv_setup_args(int argc, char** argv) {
|
||||||
process_title = argc > 0 ? uv__strdup(argv[0]) : NULL;
|
process_title = argc > 0 ? uv__strdup(argv[0]) : NULL;
|
||||||
|
uv_saved_argv0 = argc > 0 ? uv__strdup(argv[0]) : NULL;
|
||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -591,4 +591,6 @@ int uv__get_constrained_cpu(long long* quota);
|
|||||||
#define UV__KQUEUE_EVFILT_USER 0
|
#define UV__KQUEUE_EVFILT_USER 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern char* uv_saved_argv0;
|
||||||
|
|
||||||
#endif /* UV_UNIX_INTERNAL_H_ */
|
#endif /* UV_UNIX_INTERNAL_H_ */
|
||||||
|
|||||||
@ -59,54 +59,13 @@ void uv_loadavg(double avg[3]) {
|
|||||||
|
|
||||||
|
|
||||||
int uv_exepath(char* buffer, size_t* size) {
|
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)
|
if (buffer == NULL || size == NULL || *size == 0)
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
|
|
||||||
mypid = getpid();
|
if (uv_saved_argv0 == NULL)
|
||||||
for (;;) {
|
return UV_EINVAL;
|
||||||
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 (argsbuf[0] == NULL) {
|
return uv__search_path(uv_saved_argv0, buffer, size);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -35,9 +35,6 @@ TEST_IMPL(get_currentexe) {
|
|||||||
#if defined(__QEMU__)
|
#if defined(__QEMU__)
|
||||||
RETURN_SKIP("Test does not currently work in QEMU");
|
RETURN_SKIP("Test does not currently work in QEMU");
|
||||||
#endif
|
#endif
|
||||||
#if defined(__OpenBSD__)
|
|
||||||
RETURN_SKIP("Test does not currently work in OpenBSD");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char buffer[PATHMAX];
|
char buffer[PATHMAX];
|
||||||
char path[PATHMAX];
|
char path[PATHMAX];
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user