Skip to content
Snippets Groups Projects
Commit ec6c0041 authored by Tobias Klauser's avatar Tobias Klauser Committed by Tobias Klauser
Browse files

syscall: use fcntl F_DUP2FD_CLOEXEC in forkAndExecInChild on illumos

Use fcntl(oldfd, F_DUP2FD_CLOEXEC, newfd) to duplicate the file
descriptor and mark is as close-on-exec instead of dup2 & fcntl.

Illumos implements dup3 like this in libc.

Change-Id: I9782bce553ffb832e9b1a12bbf3c0a40c821f56e
Reviewed-on: https://go-review.googlesource.com/c/go/+/358374


Trust: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent adfb85b3
No related branches found
No related tags found
No related merge requests found
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
package syscall package syscall
import ( import (
"runtime"
"unsafe" "unsafe"
) )
...@@ -197,11 +198,19 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr ...@@ -197,11 +198,19 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
// Pass 1: look for fd[i] < i and move those up above len(fd) // Pass 1: look for fd[i] < i and move those up above len(fd)
// so that pass 2 won't stomp on an fd it needs later. // so that pass 2 won't stomp on an fd it needs later.
if pipe < nextfd { if pipe < nextfd {
_, err1 = dup2child(uintptr(pipe), uintptr(nextfd)) switch runtime.GOOS {
case "illumos":
_, err1 = fcntl1(uintptr(pipe), _F_DUP2FD_CLOEXEC, uintptr(nextfd))
default:
_, err1 = dup2child(uintptr(pipe), uintptr(nextfd))
if err1 != 0 {
goto childerror
}
_, err1 = fcntl1(uintptr(nextfd), F_SETFD, FD_CLOEXEC)
}
if err1 != 0 { if err1 != 0 {
goto childerror goto childerror
} }
fcntl1(uintptr(nextfd), F_SETFD, FD_CLOEXEC)
pipe = nextfd pipe = nextfd
nextfd++ nextfd++
} }
...@@ -210,11 +219,16 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr ...@@ -210,11 +219,16 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
if nextfd == pipe { // don't stomp on pipe if nextfd == pipe { // don't stomp on pipe
nextfd++ nextfd++
} }
_, err1 = dup2child(uintptr(fd[i]), uintptr(nextfd)) switch runtime.GOOS {
if err1 != 0 { case "illumos":
goto childerror _, err1 = fcntl1(uintptr(fd[i]), _F_DUP2FD_CLOEXEC, uintptr(nextfd))
default:
_, err1 = dup2child(uintptr(fd[i]), uintptr(nextfd))
if err1 != 0 {
goto childerror
}
_, err1 = fcntl1(uintptr(nextfd), F_SETFD, FD_CLOEXEC)
} }
_, err1 = fcntl1(uintptr(nextfd), F_SETFD, FD_CLOEXEC)
if err1 != 0 { if err1 != 0 {
goto childerror goto childerror
} }
......
...@@ -31,6 +31,8 @@ const ( ...@@ -31,6 +31,8 @@ const (
F_DUPFD_CLOEXEC = 0 F_DUPFD_CLOEXEC = 0
// AF_LOCAL doesn't exist on AIX // AF_LOCAL doesn't exist on AIX
AF_LOCAL = AF_UNIX AF_LOCAL = AF_UNIX
_F_DUP2FD_CLOEXEC = 0
) )
func (ts *StTimespec_t) Unix() (sec int64, nsec int64) { func (ts *StTimespec_t) Unix() (sec int64, nsec int64) {
......
...@@ -14,6 +14,8 @@ package syscall ...@@ -14,6 +14,8 @@ package syscall
import "unsafe" import "unsafe"
const _F_DUP2FD_CLOEXEC = F_DUP2FD_CLOEXEC
// Implemented in asm_solaris_amd64.s. // Implemented in asm_solaris_amd64.s.
func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment