Download raw body.
Go - getexecpath() support
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
Go - getexecpath() support