Commit 2d1bd1fe authored by Shawn Walker-Salas's avatar Shawn Walker-Salas Committed by Brad Fitzpatrick

syscall: fix Exec on solaris

The test added for issue #18146 exposed a long-existing bug in the
Solaris port; notably, that syscall.Exec uses RawSyscall -- which is not
actually functional for the Solaris port (intentionally) and only exists
as a placebo to satisfy build requirements.

Call syscall.execve instead for Solaris.

Fixes #20832

Change-Id: I327d863f4bbbbbb6e5ecf66b82152c4030825d09
Reviewed-on: https://go-review.googlesource.com/47032
Run-TryBot: Shawn Walker-Salas <shawn.walker@oracle.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent cfb8404e
......@@ -41,6 +41,11 @@ func setuid(uid uintptr) (err Errno)
func setpgid(pid uintptr, pgid uintptr) (err Errno)
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() {
execveSolaris = execve
}
// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
// If a dup or exec fails, write the errno error to pipe.
// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
......
......@@ -246,6 +246,10 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
func runtime_BeforeExec()
func runtime_AfterExec()
// execveSolaris is non-nil on Solaris, set to execve in exec_solaris.go; this
// avoids a build dependency for other platforms.
var execveSolaris func(path uintptr, argv uintptr, envp uintptr) (err Errno)
// Exec invokes the execve(2) system call.
func Exec(argv0 string, argv []string, envv []string) (err error) {
argv0p, err := BytePtrFromString(argv0)
......@@ -261,10 +265,20 @@ func Exec(argv0 string, argv []string, envv []string) (err error) {
return err
}
runtime_BeforeExec()
_, _, err1 := RawSyscall(SYS_EXECVE,
uintptr(unsafe.Pointer(argv0p)),
uintptr(unsafe.Pointer(&argvp[0])),
uintptr(unsafe.Pointer(&envvp[0])))
var err1 Errno
if runtime.GOOS == "solaris" {
// RawSyscall should never be used on Solaris.
err1 = execveSolaris(
uintptr(unsafe.Pointer(argv0p)),
uintptr(unsafe.Pointer(&argvp[0])),
uintptr(unsafe.Pointer(&envvp[0])))
} else {
_, _, err1 = RawSyscall(SYS_EXECVE,
uintptr(unsafe.Pointer(argv0p)),
uintptr(unsafe.Pointer(&argvp[0])),
uintptr(unsafe.Pointer(&envvp[0])))
}
runtime_AfterExec()
return Errno(err1)
return err1
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment