]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: use fcntl F_DUP2FD_CLOEXEC in forkAndExecInChild on illumos
authorTobias Klauser <tklauser@distanz.ch>
Mon, 25 Oct 2021 11:37:29 +0000 (13:37 +0200)
committerTobias Klauser <tobias.klauser@gmail.com>
Tue, 26 Oct 2021 05:02:53 +0000 (05:02 +0000)
Use fcntl(oldfd, F_DUP2FD_CLOEXEC, newfd) to duplicate the file
descriptor and mark is as close-on-exec instead of dup2 & fcntl.

Illumos implements dup3 like this in libc.

Change-Id: I9782bce553ffb832e9b1a12bbf3c0a40c821f56e
Reviewed-on: https://go-review.googlesource.com/c/go/+/358374
Trust: Tobias Klauser <tobias.klauser@gmail.com>
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/syscall/exec_libc.go
src/syscall/syscall_aix.go
src/syscall/syscall_solaris.go

index 8a84954051a1dc42526fe78e85004d158aac5738..b14abd4e63b35e9c0c7af61e34fcd8d2fd5bedba 100644 (file)
@@ -10,6 +10,7 @@
 package syscall
 
 import (
+       "runtime"
        "unsafe"
 )
 
@@ -197,11 +198,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 = dup2child(uintptr(pipe), uintptr(nextfd))
+               switch runtime.GOOS {
+               case "illumos":
+                       _, err1 = fcntl1(uintptr(pipe), _F_DUP2FD_CLOEXEC, uintptr(nextfd))
+               default:
+                       _, err1 = dup2child(uintptr(pipe), uintptr(nextfd))
+                       if err1 != 0 {
+                               goto childerror
+                       }
+                       _, err1 = fcntl1(uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+               }
                if err1 != 0 {
                        goto childerror
                }
-               fcntl1(uintptr(nextfd), F_SETFD, FD_CLOEXEC)
                pipe = nextfd
                nextfd++
        }
@@ -210,11 +219,16 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
                        if nextfd == pipe { // don't stomp on pipe
                                nextfd++
                        }
-                       _, err1 = dup2child(uintptr(fd[i]), uintptr(nextfd))
-                       if err1 != 0 {
-                               goto childerror
+                       switch runtime.GOOS {
+                       case "illumos":
+                               _, err1 = fcntl1(uintptr(fd[i]), _F_DUP2FD_CLOEXEC, uintptr(nextfd))
+                       default:
+                               _, err1 = dup2child(uintptr(fd[i]), uintptr(nextfd))
+                               if err1 != 0 {
+                                       goto childerror
+                               }
+                               _, err1 = fcntl1(uintptr(nextfd), F_SETFD, FD_CLOEXEC)
                        }
-                       _, err1 = fcntl1(uintptr(nextfd), F_SETFD, FD_CLOEXEC)
                        if err1 != 0 {
                                goto childerror
                        }
index 9c6afba442e2f2adf2227fb05845af8aeee9ddc4..20e77ac875e584482add6ac67dd5b16cf5303a24 100644 (file)
@@ -31,6 +31,8 @@ const (
        F_DUPFD_CLOEXEC = 0
        // AF_LOCAL doesn't exist on AIX
        AF_LOCAL = AF_UNIX
+
+       _F_DUP2FD_CLOEXEC = 0
 )
 
 func (ts *StTimespec_t) Unix() (sec int64, nsec int64) {
index daa4b88a71d6fcb6d9d03c3048006d52fd9c135f..dedfbd03c08f7f212cfc66d006a2ce93f49f7bf6 100644 (file)
@@ -14,6 +14,8 @@ package syscall
 
 import "unsafe"
 
+const _F_DUP2FD_CLOEXEC = F_DUP2FD_CLOEXEC
+
 // Implemented in asm_solaris_amd64.s.
 func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
 func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)