syscall: simplify execve handling on libc platforms

Rather than providing three different execve variables for different
platforms, use a single variable. Provide a small wrapper that handles
conversion to uintptr for the AIX/Solaris case.

Note that this removes special handling for openbsd/mips64, which is
now a dead port.

Updates #61546

Change-Id: I3d6387c31669f64bfb61639536803e595f478647
Reviewed-on: https://go-review.googlesource.com/c/go/+/693880
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Carlos Amedee <carlos@golang.org>
This commit is contained in:
Joel Sing 2025-08-10 00:40:07 +10:00 committed by Gopher Robot
parent ba840c1bf9
commit 8dcab6f450
4 changed files with 16 additions and 19 deletions

View file

@ -61,7 +61,13 @@ func write1(fd uintptr, buf uintptr, nbyte uintptr) (n uintptr, err Errno)
// syscall defines this global on our behalf to avoid a build dependency on other platforms
func init() {
execveLibc = execve
execveLibc = execveLibcWrapper
}
func execveLibcWrapper(path *byte, argv **byte, envp **byte) error {
return execve(uintptr(unsafe.Pointer(path)),
uintptr(unsafe.Pointer(argv)),
uintptr(unsafe.Pointer(envp)))
}
// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.

View file

@ -265,9 +265,7 @@ func runtime_AfterExec()
// execveLibc is non-nil on OS using libc syscall, set to execve in exec_libc.go; this
// avoids a build dependency for other platforms.
var execveLibc func(path uintptr, argv uintptr, envp uintptr) Errno
var execveDarwin func(path *byte, argv **byte, envp **byte) error
var execveOpenBSD func(path *byte, argv **byte, envp **byte) error
var execveLibc func(path *byte, argv **byte, envp **byte) error
// Exec invokes the execve(2) system call.
func Exec(argv0 string, argv []string, envv []string) (err error) {
@ -291,19 +289,12 @@ func Exec(argv0 string, argv []string, envv []string) (err error) {
}
var err1 error
if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" || runtime.GOOS == "aix" {
// RawSyscall should never be used on Solaris, illumos, or AIX.
err1 = execveLibc(
uintptr(unsafe.Pointer(argv0p)),
uintptr(unsafe.Pointer(&argvp[0])),
uintptr(unsafe.Pointer(&envvp[0])))
} else if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
// Similarly on Darwin.
err1 = execveDarwin(argv0p, &argvp[0], &envvp[0])
} else if runtime.GOOS == "openbsd" && runtime.GOARCH != "mips64" {
// Similarly on OpenBSD.
err1 = execveOpenBSD(argv0p, &argvp[0], &envvp[0])
} else {
switch runtime.GOOS {
case "aix", "darwin", "illumos", "ios", "openbsd", "solaris":
// RawSyscall should never be used on these platforms.
err1 = execveLibc(argv0p, &argvp[0], &envvp[0])
default:
_, _, err1 = RawSyscall(SYS_EXECVE,
uintptr(unsafe.Pointer(argv0p)),
uintptr(unsafe.Pointer(&argvp[0])),

View file

@ -228,7 +228,7 @@ func Kill(pid int, signum Signal) (err error) { return kill(pid, int(signum), 1)
//sys getcwd(buf []byte) (n int, err error)
func init() {
execveDarwin = execve
execveLibc = execve
}
func fdopendir(fd int) (dir uintptr, err error) {

View file

@ -13,7 +13,7 @@ import (
var dupTrampoline = abi.FuncPCABI0(libc_dup3_trampoline)
func init() {
execveOpenBSD = execve
execveLibc = execve
}
func syscallInternal(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {