github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/src/net/sys_cloexec.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // This file implements sysSocket and accept for platforms that do not 6 // provide a fast path for setting SetNonblock and CloseOnExec. 7 8 // +build darwin dragonfly nacl netbsd openbsd solaris 9 10 package net 11 12 import ( 13 "os" 14 "syscall" 15 ) 16 17 // Wrapper around the socket system call that marks the returned file 18 // descriptor as nonblocking and close-on-exec. 19 func sysSocket(family, sotype, proto int) (int, error) { 20 // See ../syscall/exec_unix.go for description of ForkLock. 21 syscall.ForkLock.RLock() 22 s, err := socketFunc(family, sotype, proto) 23 if err == nil { 24 syscall.CloseOnExec(s) 25 } 26 syscall.ForkLock.RUnlock() 27 if err != nil { 28 return -1, os.NewSyscallError("socket", err) 29 } 30 if err = syscall.SetNonblock(s, true); err != nil { 31 closeFunc(s) 32 return -1, os.NewSyscallError("setnonblock", err) 33 } 34 return s, nil 35 } 36 37 // Wrapper around the accept system call that marks the returned file 38 // descriptor as nonblocking and close-on-exec. 39 func accept(s int) (int, syscall.Sockaddr, error) { 40 // See ../syscall/exec_unix.go for description of ForkLock. 41 // It is probably okay to hold the lock across syscall.Accept 42 // because we have put fd.sysfd into non-blocking mode. 43 // However, a call to the File method will put it back into 44 // blocking mode. We can't take that risk, so no use of ForkLock here. 45 ns, sa, err := acceptFunc(s) 46 if err == nil { 47 syscall.CloseOnExec(ns) 48 } 49 if err != nil { 50 return -1, nil, os.NewSyscallError("accept", err) 51 } 52 if err = syscall.SetNonblock(ns, true); err != nil { 53 closeFunc(ns) 54 return -1, nil, os.NewSyscallError("setnonblock", err) 55 } 56 return ns, sa, nil 57 }