Here's an attempt to switch libuv to getexecpath(3).
It builds, tests pass, afaict it behaves the same as the other
implementations (i.e. it copies a truncated path and no error
when the path doesn't fit into the buffer).
In lang/node it allows me to drop the current workaround to make
process.execPath work.
It could probably use some adult supervision, though ...
Index: Makefile
===================================================================
RCS file: /cvs/ports/devel/libuv/Makefile,v
retrieving revision 1.34
diff -u -p -r1.34 Makefile
--- Makefile 8 Mar 2026 15:14:43 -0000 1.34
+++ Makefile 8 Sep 2026 17:36:34 -0000
@@ -4,6 +4,7 @@ VER = 1.52.1
DISTNAME = libuv-v${VER}
PKGNAME = libuv-${VER}
CATEGORIES = devel
+REVISION = 0
SHARED_LIBS += uv 5.3 # 1.0
Index: patches/patch-src_unix_openbsd_c
===================================================================
RCS file: patches/patch-src_unix_openbsd_c
diff -N patches/patch-src_unix_openbsd_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_unix_openbsd_c 8 Sep 2026 17:36:34 -0000
@@ -0,0 +1,34 @@
+Index: src/unix/openbsd.c
+--- src/unix/openbsd.c.orig
++++ src/unix/openbsd.c
+@@ -59,15 +59,26 @@ void uv_loadavg(double avg[3]) {
+
+
+ int uv_exepath(char* buffer, size_t* size) {
++ char exe_path[PATH_MAX];
++ size_t result_size;
++
+ if (buffer == NULL || size == NULL || *size == 0)
+ return UV_EINVAL;
+
+- if (uv_saved_argv0 == NULL)
+- return UV_EINVAL;
++ if (getexecpath(exe_path, sizeof(exe_path)) == -1)
++ return UV__ERR(errno);
+
+- return uv__search_path(uv_saved_argv0, buffer, size);
+-}
++ result_size = strlen(exe_path);
+
++ *size -= 1;
++ if (*size > result_size)
++ *size = result_size;
++
++ memcpy(buffer, exe_path, *size);
++ buffer[*size] = '\0';
++
++ return 0;
++}
+
+ uint64_t uv_get_free_memory(void) {
+ struct uvmexp info;