From bf7b29a53bda06b71fa09b62a162e1aedf7f2115 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Tue, 2 Jan 2024 22:12:03 +0200 Subject: [PATCH] os: improve os.executable() on OpenBSD (#20356) --- vlib/os/os.c.v | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/vlib/os/os.c.v b/vlib/os/os.c.v index b1b17394552886..5d75e95c9b931a 100644 --- a/vlib/os/os.c.v +++ b/vlib/os/os.c.v @@ -5,7 +5,7 @@ import strings #include // #include #include -$if freebsd { +$if freebsd || openbsd { #include } @@ -721,6 +721,33 @@ pub fn executable() string { res := unsafe { tos_clone(&result[0]) } return res } + $if openbsd { + // Sadly, unlike on FreeBSD, there is still no reliable way, to get the full path of the + // current process in OpenBSD. However, we can try our best, by first checking, if the passed + // argv[0] to the process, contains an absolute path (starting with /), according to the kernel, + // and only go use the slower PATH scanning fallback method, when it does not. + // See also https://github.com/gpakosz/whereami/blob/master/src/whereami.c#L591 + // and https://github.com/ziglang/zig/issues/6718#issuecomment-711134120 . + mut pbuf := unsafe { &&u8(&result[0]) } + bufsize := usize(max_path_buffer_size) + pid := C.getpid() + mib := [C.CTL_KERN, C.KERN_PROC_ARGS, pid, C.KERN_PROC_ARGV]! + if unsafe { C.sysctl(&mib[0], mib.len, C.NULL, &bufsize, C.NULL, 0) } == 0 { + if bufsize > max_path_buffer_size { + pbuf = unsafe { &&u8(malloc(bufsize)) } + defer { + unsafe { free(pbuf) } + } + } + if unsafe { C.sysctl(&mib[0], mib.len, pbuf, &bufsize, C.NULL, 0) } == 0 { + if unsafe { *pbuf[0] } == `/` { + res := unsafe { tos_clone(pbuf[0]) } + return res + } + } + } + return executable_fallback() + } $if netbsd { count := C.readlink(c'/proc/curproc/exe', &char(&result[0]), max_path_len) if count < 0 { @@ -748,9 +775,6 @@ pub fn executable() string { res := unsafe { tos_clone(&result[0]) } return res } - // "Sadly there is no way to get the full path of the executed file in OpenBSD." - $if openbsd { - } $if solaris { } $if haiku {