]> Cypherpunks repositories - gostls13.git/commitdiff
net: detect bad F_DUPFD_CLOEXEC on OS X 10.6
authorBrad Fitzpatrick <bradfitz@golang.org>
Tue, 6 Aug 2013 14:18:06 +0000 (07:18 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 6 Aug 2013 14:18:06 +0000 (07:18 -0700)
On 10.6, OS X's fcntl returns EBADF instead of EINVAL.

R=golang-dev, iant, dave
CC=golang-dev
https://golang.org/cl/12493043

src/pkg/net/fd_unix.go

index feced2f76132e65d81d743f1d83fd1cbff75df0e..14a3187ea564e41e39ff3a45e2bd97ba057d5875 100644 (file)
@@ -413,6 +413,19 @@ var tryDupCloexec = int32(1)
 func dupCloseOnExec(fd int) (newfd int, err error) {
        if atomic.LoadInt32(&tryDupCloexec) == 1 {
                r0, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0)
+               if runtime.GOOS == "darwin" && e1 == syscall.EBADF {
+                       // On OS X 10.6 and below (but we only support
+                       // >= 10.6), F_DUPFD_CLOEXEC is unsupported
+                       // and fcntl there falls back (undocumented)
+                       // to doing an ioctl instead, returning EBADF
+                       // in this case because fd is not of the
+                       // expected device fd type.  Treat it as
+                       // EINVAL instead, so we fall back to the
+                       // normal dup path.
+                       // TODO: only do this on 10.6 if we can detect 10.6
+                       // cheaply.
+                       e1 = syscall.EINVAL
+               }
                switch e1 {
                case 0:
                        return int(r0), nil