10
10
package net
11
11
12
12
import (
13
+ "internal/poll"
13
14
"os"
14
15
"syscall"
15
16
)
@@ -18,8 +19,32 @@ import (
18
19
// descriptor as nonblocking and close-on-exec.
19
20
func sysSocket (family , sotype , proto int ) (int , error ) {
20
21
s , err := socketFunc (family , sotype | syscall .SOCK_NONBLOCK | syscall .SOCK_CLOEXEC , proto )
22
+ // On Linux the SOCK_NONBLOCK and SOCK_CLOEXEC flags were
23
+ // introduced in 2.6.27 kernel and on FreeBSD both flags were
24
+ // introduced in 10 kernel. If we get an EINVAL error on Linux
25
+ // or EPROTONOSUPPORT error on FreeBSD, fall back to using
26
+ // socket without them.
27
+ switch err {
28
+ case nil :
29
+ return s , nil
30
+ default :
31
+ return - 1 , os .NewSyscallError ("socket" , err )
32
+ case syscall .EPROTONOSUPPORT , syscall .EINVAL :
33
+ }
34
+
35
+ // See ../syscall/exec_unix.go for description of ForkLock.
36
+ syscall .ForkLock .RLock ()
37
+ s , err = socketFunc (family , sotype , proto )
38
+ if err == nil {
39
+ syscall .CloseOnExec (s )
40
+ }
41
+ syscall .ForkLock .RUnlock ()
21
42
if err != nil {
22
43
return - 1 , os .NewSyscallError ("socket" , err )
23
44
}
45
+ if err = syscall .SetNonblock (s , true ); err != nil {
46
+ poll .CloseFunc (s )
47
+ return - 1 , os .NewSyscallError ("setnonblock" , err )
48
+ }
24
49
return s , nil
25
50
}
0 commit comments