]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: use dup3 in forkAndExecInChild on NetBSD
authorTobias Klauser <tklauser@distanz.ch>
Tue, 26 Oct 2021 07:13:16 +0000 (09:13 +0200)
committerTobias Klauser <tobias.klauser@gmail.com>
Wed, 27 Oct 2021 06:23:35 +0000 (06:23 +0000)
Use dup3(oldfd, newfd, O_CLOEXEC) to atomically duplicate the file
descriptor and mark is as close-on-exec instead of dup2 & fcntl.

The dup3 syscall was added in NetBSD 6.0.

Change-Id: I01a4f8c62bfa8fb7f9f3166070380dd2002bb564
Reviewed-on: https://go-review.googlesource.com/c/go/+/358755
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Trust: Benny Siegert <bsiegert@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Benny Siegert <bsiegert@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>

src/syscall/exec_bsd.go
src/syscall/syscall_dragonfly.go
src/syscall/syscall_netbsd.go
src/syscall/syscall_openbsd_mips64.go

index 4c36f9ec132d8a6497e1ebd266ebad9433745f0f..d2e50e3dd34e28deb81e7c82f5813457bef8e8e4 100644 (file)
@@ -8,6 +8,7 @@
 package syscall
 
 import (
+       "runtime"
        "unsafe"
 )
 
@@ -181,11 +182,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)
        // so that pass 2 won't stomp on an fd it needs later.
        if pipe < nextfd {
-               _, _, err1 = RawSyscall(SYS_DUP2, uintptr(pipe), uintptr(nextfd), 0)
-               if err1 != 0 {
-                       goto childerror
+               switch runtime.GOOS {
+               case "netbsd":
+                       _, _, err1 = RawSyscall(_SYS_DUP3, uintptr(pipe), uintptr(nextfd), O_CLOEXEC)
+                       if err1 != 0 {
+                               goto childerror
+                       }
+               default:
+                       _, _, err1 = RawSyscall(SYS_DUP2, uintptr(pipe), uintptr(nextfd), 0)
+                       if err1 != 0 {
+                               goto childerror
+                       }
+                       RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
                }
-               RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
                pipe = nextfd
                nextfd++
        }
@@ -194,11 +203,19 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
                        if nextfd == pipe { // don't stomp on pipe
                                nextfd++
                        }
-                       _, _, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(nextfd), 0)
-                       if err1 != 0 {
-                               goto childerror
+                       switch runtime.GOOS {
+                       case "netbsd":
+                               _, _, err1 = RawSyscall(_SYS_DUP3, uintptr(fd[i]), uintptr(nextfd), O_CLOEXEC)
+                               if err1 != 0 {
+                                       goto childerror
+                               }
+                       default:
+                               _, _, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(nextfd), 0)
+                               if err1 != 0 {
+                                       goto childerror
+                               }
+                               RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
                        }
-                       RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
                        fd[i] = nextfd
                        nextfd++
                }
index 16adf306d50a0c7e085c890730ac189a684cb1b4..cc92c4a93edc9c50c70119b147ec020a0e23bf61 100644 (file)
@@ -17,6 +17,8 @@ import (
        "unsafe"
 )
 
+const _SYS_DUP3 = 0
+
 // See version list in https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/param.h
 var (
        osreldateOnce sync.Once
index 6f05b0d43d748783ab7474eceeed2fec7cb48cc6..cebef10be885949b984ddd1462f70479cb3fa21c 100644 (file)
@@ -14,6 +14,8 @@ package syscall
 
 import "unsafe"
 
+const _SYS_DUP3 = SYS_DUP3
+
 type SockaddrDatalink struct {
        Len    uint8
        Family uint8
index b259dc69755b7d9cd3a4f74c00ed624590386dac..e8ae2e9911bafa336ce75b93eeff422602366088 100644 (file)
@@ -4,6 +4,8 @@
 
 package syscall
 
+const _SYS_DUP3 = 0
+
 func setTimespec(sec, nsec int64) Timespec {
        return Timespec{Sec: sec, Nsec: nsec}
 }