From 1dfe3d1f6e510e7c62cf74240a53d26131042049 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 20 Dec 2011 15:41:37 -0800 Subject: [PATCH] os: don't trust O_CLOEXEC on OS X OS X 10.6 doesn't do O_CLOEXEC. OS X 10.7 does. For now, always fall back to using syscall.CloseOnExec on darwin. This can removed when 10.6 is old news, or if we find a way to cheaply & reliably detect 10.6 vs 10.7 at runtime. Fixes #2587 R=golang-dev, rsc, iant CC=golang-dev https://golang.org/cl/5500053 --- src/pkg/os/exec/exec_test.go | 5 +++-- src/pkg/os/file_unix.go | 9 +++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/pkg/os/exec/exec_test.go b/src/pkg/os/exec/exec_test.go index 0358441f86..2b4166cc3e 100644 --- a/src/pkg/os/exec/exec_test.go +++ b/src/pkg/os/exec/exec_test.go @@ -256,8 +256,9 @@ func TestHelperProcess(*testing.T) { fmt.Printf("ReadAll from fd 3: %v", err) os.Exit(1) } - // TODO(bradfitz,iant): the rest of this test is disabled - // for now. remove this block once we figure out why it fails. + // TODO(bradfitz): remove this block once the builders are restarted + // with a new binary including be47ea17bea0 (set CLOEXEC on epoll/kqueue fds) + // and 5500053 (don't trust O_CLOEXEC on OS X). { os.Stderr.Write(bs) os.Exit(0) diff --git a/src/pkg/os/file_unix.go b/src/pkg/os/file_unix.go index cea305abe9..9e5d0add83 100644 --- a/src/pkg/os/file_unix.go +++ b/src/pkg/os/file_unix.go @@ -68,8 +68,13 @@ func OpenFile(name string, flag int, perm uint32) (file *File, err error) { } // There's a race here with fork/exec, which we are - // content to live with. See ../syscall/exec.go - if syscall.O_CLOEXEC == 0 { // O_CLOEXEC not supported + // content to live with. See ../syscall/exec_unix.go. + // On OS X 10.6, the O_CLOEXEC flag is not respected. + // On OS X 10.7, the O_CLOEXEC flag works. + // Without a cheap & reliable way to detect 10.6 vs 10.7 at + // runtime, we just always call syscall.CloseOnExec on Darwin. + // Once >=10.7 is prevalent, this extra call can removed. + if syscall.O_CLOEXEC == 0 || runtime.GOOS == "darwin" { // O_CLOEXEC not supported syscall.CloseOnExec(r) }