1
0
mirror of https://github.com/golang/go synced 2024-11-17 21:14:44 -07:00

syscall: use dup3 in forkAndExecInChild1 if available

The dup3 syscall is available since Linux 2.6.27. Fall back to dup2 (if
available) if dup3 returns ENOSYS.

This allows to omit the additional fcntl call to mark the dup'ed fd as
close-on-exec.

Change-Id: If318b593edd783f2aa988534c6062498e7119ddb
Reviewed-on: https://go-review.googlesource.com/c/go/+/220422
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Tobias Klauser 2020-02-23 18:14:34 +01:00 committed by Tobias Klauser
parent 87c0db9916
commit 31acdcc701

View File

@ -434,11 +434,16 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att
// 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 = RawSyscall(SYS_DUP3, uintptr(pipe), uintptr(nextfd), O_CLOEXEC)
if _SYS_dup != SYS_DUP3 && err1 == ENOSYS {
_, _, err1 = RawSyscall(_SYS_dup, uintptr(pipe), uintptr(nextfd), 0) _, _, err1 = RawSyscall(_SYS_dup, uintptr(pipe), uintptr(nextfd), 0)
if err1 != 0 { if err1 != 0 {
goto childerror goto childerror
} }
RawSyscall(fcntl64Syscall, uintptr(nextfd), F_SETFD, FD_CLOEXEC) RawSyscall(fcntl64Syscall, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
} else if err1 != 0 {
goto childerror
}
pipe = nextfd pipe = nextfd
nextfd++ nextfd++
} }
@ -447,11 +452,16 @@ func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, att
if nextfd == pipe { // don't stomp on pipe if nextfd == pipe { // don't stomp on pipe
nextfd++ nextfd++
} }
_, _, err1 = RawSyscall(_SYS_dup, uintptr(fd[i]), uintptr(nextfd), 0) _, _, err1 = RawSyscall(SYS_DUP3, uintptr(fd[i]), uintptr(nextfd), O_CLOEXEC)
if _SYS_dup != SYS_DUP3 && err1 == ENOSYS {
_, _, err1 = RawSyscall(_SYS_dup, uintptr(pipe), uintptr(nextfd), 0)
if err1 != 0 { if err1 != 0 {
goto childerror goto childerror
} }
RawSyscall(fcntl64Syscall, uintptr(nextfd), F_SETFD, FD_CLOEXEC) RawSyscall(fcntl64Syscall, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
} else if err1 != 0 {
goto childerror
}
fd[i] = nextfd fd[i] = nextfd
nextfd++ nextfd++
} }