net: detect bad F_DUPFD_CLOEXEC on OS X 10.6
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
diff --git a/src/pkg/net/fd_unix.go b/src/pkg/net/fd_unix.go
index feced2f..14a3187 100644
--- a/src/pkg/net/fd_unix.go
+++ b/src/pkg/net/fd_unix.go
@@ -413,6 +413,19 @@
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