From: Mikio Hara Date: Tue, 4 Mar 2014 00:28:09 +0000 (+0900) Subject: net: enable fast socket creation with close-on-exec flag on freebsd X-Git-Tag: go1.3beta1~502 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=1d086e39b09e6fa3b5e87da5dd6ed8154319f1db;p=gostls13.git net: enable fast socket creation with close-on-exec flag on freebsd Also makes variable names explicit. Fixes #7186. LGTM=iant R=golang-codereviews, gobot, iant, bradfitz CC=golang-codereviews https://golang.org/cl/69100043 --- diff --git a/src/pkg/net/sock_cloexec.go b/src/pkg/net/sock_cloexec.go index 3f22cd8f57..18ff64388c 100644 --- a/src/pkg/net/sock_cloexec.go +++ b/src/pkg/net/sock_cloexec.go @@ -5,7 +5,7 @@ // This file implements sysSocket and accept for platforms that // provide a fast path for setting SetNonblock and CloseOnExec. -// +build linux +// +build freebsd linux package net @@ -13,18 +13,20 @@ import "syscall" // Wrapper around the socket system call that marks the returned file // descriptor as nonblocking and close-on-exec. -func sysSocket(f, t, p int) (int, error) { - s, err := syscall.Socket(f, t|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, p) - // The SOCK_NONBLOCK and SOCK_CLOEXEC flags were introduced in - // Linux 2.6.27. If we get an EINVAL error, fall back to - // using socket without them. - if err == nil || err != syscall.EINVAL { +func sysSocket(family, sotype, proto int) (int, error) { + s, err := syscall.Socket(family, sotype|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, proto) + // On Linux the SOCK_NONBLOCK and SOCK_CLOEXEC flags were + // introduced in 2.6.27 kernel and on FreeBSD both flags were + // introduced in 10 kernel. If we get an EINVAL error on Linux + // or EPROTONOSUPPORT error on FreeBSD, fall back to using + // socket without them. + if err == nil || (err != syscall.EPROTONOSUPPORT && err != syscall.EINVAL) { return s, err } // See ../syscall/exec_unix.go for description of ForkLock. syscall.ForkLock.RLock() - s, err = syscall.Socket(f, t, p) + s, err = syscall.Socket(family, sotype, proto) if err == nil { syscall.CloseOnExec(s) } @@ -41,12 +43,14 @@ func sysSocket(f, t, p int) (int, error) { // Wrapper around the accept system call that marks the returned file // descriptor as nonblocking and close-on-exec. -func accept(fd int) (int, syscall.Sockaddr, error) { - nfd, sa, err := syscall.Accept4(fd, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC) - // The accept4 system call was introduced in Linux 2.6.28. If - // we get an ENOSYS or EINVAL error, fall back to using accept. +func accept(s int) (int, syscall.Sockaddr, error) { + ns, sa, err := syscall.Accept4(s, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC) + // On Linux the accept4 system call was introduced in 2.6.28 + // kernel and on FreeBSD it was introduced in 10 kernel. If we + // get an ENOSYS error on both Linux and FreeBSD, or EINVAL + // error on Linux, fall back to using accept. if err == nil || (err != syscall.ENOSYS && err != syscall.EINVAL) { - return nfd, sa, err + return ns, sa, err } // See ../syscall/exec_unix.go for description of ForkLock. @@ -54,16 +58,16 @@ func accept(fd int) (int, syscall.Sockaddr, error) { // because we have put fd.sysfd into non-blocking mode. // However, a call to the File method will put it back into // blocking mode. We can't take that risk, so no use of ForkLock here. - nfd, sa, err = syscall.Accept(fd) + ns, sa, err = syscall.Accept(s) if err == nil { - syscall.CloseOnExec(nfd) + syscall.CloseOnExec(ns) } if err != nil { return -1, nil, err } - if err = syscall.SetNonblock(nfd, true); err != nil { - syscall.Close(nfd) + if err = syscall.SetNonblock(ns, true); err != nil { + syscall.Close(ns) return -1, nil, err } - return nfd, sa, nil + return ns, sa, nil } diff --git a/src/pkg/net/sys_cloexec.go b/src/pkg/net/sys_cloexec.go index 19ba0fc00c..898fb7c0c2 100644 --- a/src/pkg/net/sys_cloexec.go +++ b/src/pkg/net/sys_cloexec.go @@ -5,7 +5,7 @@ // This file implements sysSocket and accept for platforms that do not // provide a fast path for setting SetNonblock and CloseOnExec. -// +build darwin dragonfly freebsd nacl netbsd openbsd solaris +// +build darwin dragonfly nacl netbsd openbsd solaris package net @@ -13,10 +13,10 @@ import "syscall" // Wrapper around the socket system call that marks the returned file // descriptor as nonblocking and close-on-exec. -func sysSocket(f, t, p int) (int, error) { +func sysSocket(family, sotype, proto int) (int, error) { // See ../syscall/exec_unix.go for description of ForkLock. syscall.ForkLock.RLock() - s, err := syscall.Socket(f, t, p) + s, err := syscall.Socket(family, sotype, proto) if err == nil { syscall.CloseOnExec(s) } @@ -33,22 +33,22 @@ func sysSocket(f, t, p int) (int, error) { // Wrapper around the accept system call that marks the returned file // descriptor as nonblocking and close-on-exec. -func accept(fd int) (int, syscall.Sockaddr, error) { +func accept(s int) (int, syscall.Sockaddr, error) { // See ../syscall/exec_unix.go for description of ForkLock. // It is probably okay to hold the lock across syscall.Accept // because we have put fd.sysfd into non-blocking mode. // However, a call to the File method will put it back into // blocking mode. We can't take that risk, so no use of ForkLock here. - nfd, sa, err := syscall.Accept(fd) + ns, sa, err := syscall.Accept(s) if err == nil { - syscall.CloseOnExec(nfd) + syscall.CloseOnExec(ns) } if err != nil { return -1, nil, err } - if err = syscall.SetNonblock(nfd, true); err != nil { - syscall.Close(nfd) + if err = syscall.SetNonblock(ns, true); err != nil { + syscall.Close(ns) return -1, nil, err } - return nfd, sa, nil + return ns, sa, nil }