From: Brad Smith Subject: Re: Go - getexecpath() support To: ports@openbsd.org Cc: Joel Sing Date: Wed, 7 Oct 2026 18:30:20 -0400 ping. On 2026-10-04 5:45 a.m., Brad Smith wrote: > Here is a diff for Go to make use of getexecpath() > for os.Executable(). > > Tested on aarch64 and amd64. > > > Index: Makefile > =================================================================== > RCS file: /cvs/ports/lang/go/Makefile,v > retrieving revision 1.184 > diff -u -p -u -p -r1.184 Makefile > --- Makefile 16 Sep 2026 16:16:51 -0000 1.184 > +++ Makefile 4 Oct 2026 09:37:19 -0000 > @@ -10,6 +10,7 @@ COMMENT = Go programming language > VERSION = 1.27.1 > DISTNAME = go${VERSION}.src > PKGNAME = go-${VERSION} > +REVISION = 0 > PKGSPEC = ${FULLPKGNAME:S/go-/go-=/} > > CATEGORIES = lang > Index: patches/patch-src_internal_syscall_unix_asm_openbsd_s > =================================================================== > RCS file: patches/patch-src_internal_syscall_unix_asm_openbsd_s > diff -N patches/patch-src_internal_syscall_unix_asm_openbsd_s > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ patches/patch-src_internal_syscall_unix_asm_openbsd_s 4 Oct 2026 09:37:19 -0000 > @@ -0,0 +1,11 @@ > +- Use getexecpath() for os.Executable() > + > +Index: src/internal/syscall/unix/asm_openbsd.s > +--- src/internal/syscall/unix/asm_openbsd.s.orig > ++++ src/internal/syscall/unix/asm_openbsd.s > +@@ -22,3 +22,5 @@ TEXT ·libc_linkat_trampoline(SB),NOSPLI > + JMP libc_linkat(SB) > + TEXT ·libc_symlinkat_trampoline(SB),NOSPLIT,$0-0 > + JMP libc_symlinkat(SB) > ++TEXT ·libc_getexecpath_trampoline(SB),NOSPLIT,$0-0 > ++ JMP libc_getexecpath(SB) > Index: patches/patch-src_internal_syscall_unix_getexecpath_openbsd_go > =================================================================== > RCS file: patches/patch-src_internal_syscall_unix_getexecpath_openbsd_go > diff -N patches/patch-src_internal_syscall_unix_getexecpath_openbsd_go > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ patches/patch-src_internal_syscall_unix_getexecpath_openbsd_go 4 Oct 2026 09:37:19 -0000 > @@ -0,0 +1,31 @@ > +- Use getexecpath() for os.Executable() > + > +Index: src/internal/syscall/unix/getexecpath_openbsd.go > +--- src/internal/syscall/unix/getexecpath_openbsd.go.orig > ++++ src/internal/syscall/unix/getexecpath_openbsd.go > +@@ -0,0 +1,25 @@ > ++// Copyright 2026 The Go Authors. All rights reserved. > ++// Use of this source code is governed by a BSD-style > ++// license that can be found in the LICENSE file. > ++ > ++package unix > ++ > ++import ( > ++ "internal/abi" > ++ "unsafe" > ++) > ++ > ++//go:cgo_import_dynamic libc_getexecpath getexecpath "libc.so" > ++ > ++func libc_getexecpath_trampoline() > ++ > ++// Getexecpath copies the absolute, canonicalized pathname of the > ++// running executable into buf as a NUL-terminated string. > ++func Getexecpath(buf []byte) error { > ++ _, _, errno := syscall_syscall(abi.FuncPCABI0(libc_getexecpath_trampoline), > ++ uintptr(unsafe.Pointer(unsafe.SliceData(buf))), uintptr(len(buf)), 0) > ++ if errno != 0 { > ++ return errno > ++ } > ++ return nil > ++} > Index: patches/patch-src_os_executable_openbsd_go > =================================================================== > RCS file: patches/patch-src_os_executable_openbsd_go > diff -N patches/patch-src_os_executable_openbsd_go > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ patches/patch-src_os_executable_openbsd_go 4 Oct 2026 09:37:19 -0000 > @@ -0,0 +1,24 @@ > +- Use getexecpath() for os.Executable() > + > +Index: src/os/executable_openbsd.go > +--- src/os/executable_openbsd.go.orig > ++++ src/os/executable_openbsd.go > +@@ -0,0 +1,18 @@ > ++// Copyright 2026 The Go Authors. All rights reserved. > ++// Use of this source code is governed by a BSD-style > ++// license that can be found in the LICENSE file. > ++ > ++package os > ++ > ++import ( > ++ "internal/bytealg" > ++ "internal/syscall/unix" > ++) > ++ > ++func executable() (string, error) { > ++ var buf [1024]byte // PATH_MAX; the kernel caps the path at this length > ++ if err := unix.Getexecpath(buf[:]); err != nil { > ++ return "", NewSyscallError("getexecpath", err) > ++ } > ++ return string(buf[:bytealg.IndexByte(buf[:], 0)]), nil > ++} > Index: patches/patch-src_os_executable_path_go > =================================================================== > RCS file: patches/patch-src_os_executable_path_go > diff -N patches/patch-src_os_executable_path_go > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ patches/patch-src_os_executable_path_go 4 Oct 2026 09:37:19 -0000 > @@ -0,0 +1,14 @@ > +- Use getexecpath() for os.Executable() > + > +Index: src/os/executable_path.go > +--- src/os/executable_path.go.orig > ++++ src/os/executable_path.go > +@@ -2,7 +2,7 @@ > + // Use of this source code is governed by a BSD-style > + // license that can be found in the LICENSE file. > + > +-//go:build aix || openbsd > ++//go:build aix > + > + package os > + > Index: patches/patch-src_os_executable_test_go > =================================================================== > RCS file: patches/patch-src_os_executable_test_go > diff -N patches/patch-src_os_executable_test_go > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ patches/patch-src_os_executable_test_go 4 Oct 2026 09:37:19 -0000 > @@ -0,0 +1,25 @@ > +- Use getexecpath() for os.Executable() > + > +Index: src/os/executable_test.go > +--- src/os/executable_test.go.orig > ++++ src/os/executable_test.go > +@@ -48,8 +48,8 @@ func TestExecutable(t *testing.T) { > + // make child start with a relative program path > + cmd.Dir = dir > + cmd.Path = fn > +- if runtime.GOOS == "openbsd" || runtime.GOOS == "aix" { > +- // OpenBSD and AIX rely on argv[0] > ++ if runtime.GOOS == "aix" { > ++ // AIX relies on argv[0] > + } else { > + // forge argv[0] for child, so that we can verify we could correctly > + // get real path of the executable without influenced by argv[0]. > +@@ -86,7 +86,7 @@ func TestExecutableDeleted(t *testing.T) > + switch runtime.GOOS { > + case "windows", "plan9": > + t.Skipf("%v does not support deleting running binary", runtime.GOOS) > +- case "openbsd", "freebsd", "aix": > ++ case "freebsd", "aix": > + t.Skipf("%v does not support reading deleted binary name", runtime.GOOS) > + } > + t.Parallel() > Index: pkg/PLIST > =================================================================== > RCS file: /cvs/ports/lang/go/pkg/PLIST,v > retrieving revision 1.100 > diff -u -p -u -p -r1.100 PLIST > --- pkg/PLIST 16 Sep 2026 16:16:51 -0000 1.100 > +++ pkg/PLIST 4 Oct 2026 09:37:20 -0000 > @@ -9188,6 +9188,7 @@ go/src/internal/syscall/unix/fchmodat_te > go/src/internal/syscall/unix/fcntl_js.go > go/src/internal/syscall/unix/fcntl_unix.go > go/src/internal/syscall/unix/fcntl_wasip1.go > +go/src/internal/syscall/unix/getexecpath_openbsd.go > go/src/internal/syscall/unix/getrandom.go > go/src/internal/syscall/unix/getrandom_dragonfly.go > go/src/internal/syscall/unix/getrandom_freebsd.go > @@ -10843,6 +10844,7 @@ go/src/os/executable_darwin.go > go/src/os/executable_dragonfly.go > go/src/os/executable_freebsd.go > go/src/os/executable_netbsd.go > +go/src/os/executable_openbsd.go > go/src/os/executable_path.go > go/src/os/executable_plan9.go > go/src/os/executable_procfs.go