diff options
author | Michael Stapelberg <stapelberg@debian.org> | 2014-06-19 09:22:53 +0200 |
---|---|---|
committer | Michael Stapelberg <stapelberg@debian.org> | 2014-06-19 09:22:53 +0200 |
commit | 8a39ee361feb9bf46d728ff1ba4f07ca1d9610b1 (patch) | |
tree | 4449f2036cccf162e8417cc5841a35815b3e7ac5 /src/pkg/net/sock_cloexec.go | |
parent | c8bf49ef8a92e2337b69c14b9b88396efe498600 (diff) | |
download | golang-8a39ee361feb9bf46d728ff1ba4f07ca1d9610b1.tar.gz |
Imported Upstream version 1.3upstream/1.3
Diffstat (limited to 'src/pkg/net/sock_cloexec.go')
-rw-r--r-- | src/pkg/net/sock_cloexec.go | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/src/pkg/net/sock_cloexec.go b/src/pkg/net/sock_cloexec.go index 3f22cd8f5..dec81855b 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,19 @@ 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. - if err == nil || (err != syscall.ENOSYS && err != syscall.EINVAL) { - return nfd, sa, err +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. + switch err { + default: // nil and errors other than the ones listed + return ns, sa, err + case syscall.ENOSYS: // syscall missing + case syscall.EINVAL: // some Linux use this instead of ENOSYS + case syscall.EACCES: // some Linux use this instead of ENOSYS + case syscall.EFAULT: // some Linux use this instead of ENOSYS } // See ../syscall/exec_unix.go for description of ForkLock. @@ -54,16 +63,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 } |