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++ }