From: Tobias Klauser Date: Sun, 23 Feb 2020 17:14:34 +0000 (+0100) Subject: syscall: use dup3 in forkAndExecInChild1 if available X-Git-Tag: go1.15beta1~1116 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=31acdcc701cb97040832bce371fdd8985fbea131;p=gostls13.git 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 TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- 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++ }