@@ -15,8 +15,36 @@ import "syscall"
15
15
// descriptor as nonblocking and close-on-exec.
16
16
func accept (s int ) (int , syscall.Sockaddr , string , error ) {
17
17
ns , sa , err := Accept4Func (s , syscall .SOCK_NONBLOCK | syscall .SOCK_CLOEXEC )
18
- if err != nil {
18
+ // On Linux the accept4 system call was introduced in 2.6.28
19
+ // kernel and on FreeBSD it was introduced in 10 kernel. If we
20
+ // get an ENOSYS error on both Linux and FreeBSD, or EINVAL
21
+ // error on Linux, fall back to using accept.
22
+ switch err {
23
+ case nil :
24
+ return ns , sa , "" , nil
25
+ default : // errors other than the ones listed
19
26
return - 1 , sa , "accept4" , err
27
+ case syscall .ENOSYS : // syscall missing
28
+ case syscall .EINVAL : // some Linux use this instead of ENOSYS
29
+ case syscall .EACCES : // some Linux use this instead of ENOSYS
30
+ case syscall .EFAULT : // some Linux use this instead of ENOSYS
31
+ }
32
+
33
+ // See ../syscall/exec_unix.go for description of ForkLock.
34
+ // It is probably okay to hold the lock across syscall.Accept
35
+ // because we have put fd.sysfd into non-blocking mode.
36
+ // However, a call to the File method will put it back into
37
+ // blocking mode. We can't take that risk, so no use of ForkLock here.
38
+ ns , sa , err = AcceptFunc (s )
39
+ if err == nil {
40
+ syscall .CloseOnExec (ns )
41
+ }
42
+ if err != nil {
43
+ return - 1 , nil , "accept" , err
44
+ }
45
+ if err = syscall .SetNonblock (ns , true ); err != nil {
46
+ CloseFunc (ns )
47
+ return - 1 , nil , "setnonblock" , err
20
48
}
21
49
return ns , sa , "" , nil
22
50
}
0 commit comments