aboutsummaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
authorAndy Pan <i@andypan.me>2024-04-04 16:30:30 +0800
committerGopher Robot <gobot@golang.org>2024-04-14 18:17:25 +0000
commit37f482223f331c4400797f72158fcf1eaa1793c4 (patch)
tree3a182c523095b09f38e281076acde5a7810d51b7 /src/net
parent16df5330e410cfc702d942eb0cf3707ccdfd2c1d (diff)
downloadgo-37f482223f331c4400797f72158fcf1eaa1793c4.tar.gz
go-37f482223f331c4400797f72158fcf1eaa1793c4.zip
net: separate the Solaris fast/slow path of setting SOCK_* from others
Along with the removal of the slow path from Linux and *BSD. For #59359 Change-Id: I6c79594252e5e5f1c1c57c11e09458fcae3793d2 Reviewed-on: https://go-review.googlesource.com/c/go/+/577175 Reviewed-by: Damien Neil <dneil@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> Run-TryBot: Andy Pan <panjf2000@gmail.com>
Diffstat (limited to 'src/net')
-rw-r--r--src/net/sock_cloexec.go25
-rw-r--r--src/net/sock_cloexec_solaris.go47
2 files changed, 48 insertions, 24 deletions
diff --git a/src/net/sock_cloexec.go b/src/net/sock_cloexec.go
index 9eeb89746b..043522f0b6 100644
--- a/src/net/sock_cloexec.go
+++ b/src/net/sock_cloexec.go
@@ -5,12 +5,11 @@
// This file implements sysSocket for platforms that provide a fast path for
// setting SetNonblock and CloseOnExec.
-//go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris
+//go:build dragonfly || freebsd || linux || netbsd || openbsd
package net
import (
- "internal/poll"
"os"
"syscall"
)
@@ -19,30 +18,8 @@ import (
// descriptor as nonblocking and close-on-exec.
func sysSocket(family, sotype, proto int) (int, error) {
s, err := socketFunc(family, sotype|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, proto)
- // TODO: We can remove the fallback on Linux and *BSD,
- // as currently supported versions all support accept4
- // with SOCK_CLOEXEC, but Solaris does not. See issue #59359.
- switch err {
- case nil:
- return s, nil
- default:
- return -1, os.NewSyscallError("socket", err)
- case syscall.EPROTONOSUPPORT, syscall.EINVAL:
- }
-
- // See ../syscall/exec_unix.go for description of ForkLock.
- syscall.ForkLock.RLock()
- s, err = socketFunc(family, sotype, proto)
- if err == nil {
- syscall.CloseOnExec(s)
- }
- syscall.ForkLock.RUnlock()
if err != nil {
return -1, os.NewSyscallError("socket", err)
}
- if err = syscall.SetNonblock(s, true); err != nil {
- poll.CloseFunc(s)
- return -1, os.NewSyscallError("setnonblock", err)
- }
return s, nil
}
diff --git a/src/net/sock_cloexec_solaris.go b/src/net/sock_cloexec_solaris.go
new file mode 100644
index 0000000000..04c3cdf254
--- /dev/null
+++ b/src/net/sock_cloexec_solaris.go
@@ -0,0 +1,47 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements sysSocket for platforms that provide a fast path for
+// setting SetNonblock and CloseOnExec, but don't necessarily support it.
+// Support for SOCK_* flags as part of the type parameter was added to Oracle
+// Solaris in the 11.4 release. Thus, on releases prior to 11.4, we fall back
+// to the combination of socket(3c) and fcntl(2).
+
+package net
+
+import (
+ "internal/poll"
+ "internal/syscall/unix"
+ "os"
+ "syscall"
+)
+
+// Wrapper around the socket system call that marks the returned file
+// descriptor as nonblocking and close-on-exec.
+func sysSocket(family, sotype, proto int) (int, error) {
+ // Perform a cheap test and try the fast path first.
+ if unix.SupportSockNonblockCloexec() {
+ s, err := socketFunc(family, sotype|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, proto)
+ if err != nil {
+ return -1, os.NewSyscallError("socket", err)
+ }
+ return s, nil
+ }
+
+ // See ../syscall/exec_unix.go for description of ForkLock.
+ syscall.ForkLock.RLock()
+ s, err := socketFunc(family, sotype, proto)
+ if err == nil {
+ syscall.CloseOnExec(s)
+ }
+ syscall.ForkLock.RUnlock()
+ if err != nil {
+ return -1, os.NewSyscallError("socket", err)
+ }
+ if err = syscall.SetNonblock(s, true); err != nil {
+ poll.CloseFunc(s)
+ return -1, os.NewSyscallError("setnonblock", err)
+ }
+ return s, nil
+}