aboutsummaryrefslogtreecommitdiff
path: root/src/syscall
diff options
context:
space:
mode:
authorTobias Klauser <tklauser@distanz.ch>2020-02-23 18:14:34 +0100
committerTobias Klauser <tobias.klauser@gmail.com>2020-02-24 08:31:48 +0000
commit31acdcc701cb97040832bce371fdd8985fbea131 (patch)
tree40739e5585d28210734fd045be34f612751ced2c /src/syscall
parent87c0db9916f992d5e869450deccc1185f642bfc9 (diff)
downloadgo-31acdcc701cb97040832bce371fdd8985fbea131.tar.xz
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>
Diffstat (limited to 'src/syscall')
-rw-r--r--src/syscall/exec_linux.go22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
index d639565b75..f32d682493 100644
--- a/src/syscall/exec_linux.go
+++ b/src/syscall/exec_linux.go
@@ -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)
// so that pass 2 won't stomp on an fd it needs later.
if pipe < nextfd {
- _, _, err1 = RawSyscall(_SYS_dup, uintptr(pipe), uintptr(nextfd), 0)
- if err1 != 0 {
+ _, _, 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)
+ if err1 != 0 {
+ goto childerror
+ }
+ RawSyscall(fcntl64Syscall, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+ } else if err1 != 0 {
goto childerror
}
- RawSyscall(fcntl64Syscall, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
pipe = 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
nextfd++
}
- _, _, err1 = RawSyscall(_SYS_dup, uintptr(fd[i]), uintptr(nextfd), 0)
- if err1 != 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 {
+ goto childerror
+ }
+ RawSyscall(fcntl64Syscall, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+ } else if err1 != 0 {
goto childerror
}
- RawSyscall(fcntl64Syscall, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
fd[i] = nextfd
nextfd++
}