Skip to content

Commit 856ec21

Browse files
ianlancetaylorgopherbot
authored andcommitted
[release-branch.go1.18] syscall, internal/poll: fall back to accept on linux-arm
Our minimum Linux version is 2.6.32, and the accept4 system call was introduced in 2.6.28, so we use accept4 everywhere. Unfortunately, it turns out that the accept4 system call was only added to linux-arm in 2.6.36, so for linux-arm only we need to try the accept4 system call and then fall back to accept if it doesn't work. The code we use on linux-arm is the code we used in Go 1.17. On non-arm platforms we continue using the simpler code introduced in Go 1.18. Adding accept4 to the ARM Linux kernel was: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=21d93e2e29722d7832f61cc56d73fb953ee6578e For #57333 Fixes #57338 Change-Id: I6680cb54dd4d3514a6887dda8906e6708c64459d Reviewed-on: https://go-review.googlesource.com/c/go/+/457997 Reviewed-by: Tobias Klauser <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> Reviewed-by: Than McIntosh <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: David Chase <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]>
1 parent e6adccb commit 856ec21

File tree

5 files changed

+109
-16
lines changed

5 files changed

+109
-16
lines changed

src/internal/poll/sock_cloexec.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// This file implements accept for platforms that provide a fast path for
66
// setting SetNonblock and CloseOnExec.
77

8-
//go:build dragonfly || freebsd || illumos || linux || netbsd || openbsd
8+
//go:build dragonfly || freebsd || illumos || (linux && !arm) || netbsd || openbsd
99

1010
package poll
1111

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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 accept for platforms that provide a fast path for
6+
// setting SetNonblock and CloseOnExec, but don't necessarily have accept4.
7+
// This is the code we used for accept in Go 1.17 and earlier.
8+
// On Linux the accept4 system call was introduced in 2.6.28 kernel,
9+
// and our minimum requirement is 2.6.32, so we simplified the function.
10+
// Unfortunately, on ARM accept4 wasn't added until 2.6.36, so for ARM
11+
// only we continue using the older code.
12+
13+
//go:build linux && arm
14+
15+
package poll
16+
17+
import "syscall"
18+
19+
// Wrapper around the accept system call that marks the returned file
20+
// descriptor as nonblocking and close-on-exec.
21+
func accept(s int) (int, syscall.Sockaddr, string, error) {
22+
ns, sa, err := Accept4Func(s, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC)
23+
switch err {
24+
case nil:
25+
return ns, sa, "", nil
26+
default: // errors other than the ones listed
27+
return -1, sa, "accept4", err
28+
case syscall.ENOSYS: // syscall missing
29+
case syscall.EINVAL: // some Linux use this instead of ENOSYS
30+
case syscall.EACCES: // some Linux use this instead of ENOSYS
31+
case syscall.EFAULT: // some Linux use this instead of ENOSYS
32+
}
33+
34+
// See ../syscall/exec_unix.go for description of ForkLock.
35+
// It is probably okay to hold the lock across syscall.Accept
36+
// because we have put fd.sysfd into non-blocking mode.
37+
// However, a call to the File method will put it back into
38+
// blocking mode. We can't take that risk, so no use of ForkLock here.
39+
ns, sa, err = AcceptFunc(s)
40+
if err == nil {
41+
syscall.CloseOnExec(ns)
42+
}
43+
if err != nil {
44+
return -1, nil, "accept", err
45+
}
46+
if err = syscall.SetNonblock(ns, true); err != nil {
47+
CloseFunc(ns)
48+
return -1, nil, "setnonblock", err
49+
}
50+
return ns, sa, "", nil
51+
}

src/syscall/syscall_linux.go

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -546,21 +546,6 @@ func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
546546
return nil, EAFNOSUPPORT
547547
}
548548

549-
func Accept(fd int) (nfd int, sa Sockaddr, err error) {
550-
var rsa RawSockaddrAny
551-
var len _Socklen = SizeofSockaddrAny
552-
nfd, err = accept4(fd, &rsa, &len, 0)
553-
if err != nil {
554-
return
555-
}
556-
sa, err = anyToSockaddr(&rsa)
557-
if err != nil {
558-
Close(nfd)
559-
nfd = 0
560-
}
561-
return
562-
}
563-
564549
func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
565550
var rsa RawSockaddrAny
566551
var len _Socklen = SizeofSockaddrAny

src/syscall/syscall_linux_accept.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2009 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+
// We require Linux kernel version 2.6.32. The accept4 system call was
6+
// added in version 2.6.28, so in general we can use accept4.
7+
// Unfortunately, for ARM only, accept4 was added in version 2.6.36.
8+
// Handle that case here, by using a copy of the Accept function that
9+
// we used in Go 1.17.
10+
11+
//go:build linux && arm
12+
13+
package syscall
14+
15+
func Accept(fd int) (nfd int, sa Sockaddr, err error) {
16+
var rsa RawSockaddrAny
17+
var len _Socklen = SizeofSockaddrAny
18+
// Try accept4 first for Android and newer kernels.
19+
nfd, err = accept4(fd, &rsa, &len, 0)
20+
if err == ENOSYS {
21+
nfd, err = accept(fd, &rsa, &len)
22+
}
23+
if err != nil {
24+
return
25+
}
26+
sa, err = anyToSockaddr(&rsa)
27+
if err != nil {
28+
Close(nfd)
29+
nfd = 0
30+
}
31+
return
32+
}

src/syscall/syscall_linux_accept4.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2009 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 provides the Accept function used on all systems
6+
// other than arm. See syscall_linux_accept.go for why.
7+
8+
//go:build linux && !arm
9+
10+
package syscall
11+
12+
func Accept(fd int) (nfd int, sa Sockaddr, err error) {
13+
var rsa RawSockaddrAny
14+
var len _Socklen = SizeofSockaddrAny
15+
nfd, err = accept4(fd, &rsa, &len, 0)
16+
if err != nil {
17+
return
18+
}
19+
sa, err = anyToSockaddr(&rsa)
20+
if err != nil {
21+
Close(nfd)
22+
nfd = 0
23+
}
24+
return
25+
}

0 commit comments

Comments
 (0)