blob: 56dab31b1466a18cb3584671c8e906460f455c16 [file] [log] [blame]
Ian Lance Taylor31f58dc2013-01-28 08:54:15 -08001// 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
Tobias Klauser3f8e6482021-04-20 12:58:53 +02005// This file implements sysSocket for platforms that provide a fast path for
6// setting SetNonblock and CloseOnExec.
Ian Lance Taylor31f58dc2013-01-28 08:54:15 -08007
Russ Coxd4b26382021-02-19 18:35:10 -05008//go:build dragonfly || freebsd || illumos || linux || netbsd || openbsd
Ian Lance Taylor31f58dc2013-01-28 08:54:15 -08009
10package net
11
Mikio Hara055ecb72015-04-21 21:20:15 +090012import (
Ian Lance Taylor3792db52017-02-10 14:59:38 -080013 "internal/poll"
Mikio Hara055ecb72015-04-21 21:20:15 +090014 "os"
15 "syscall"
16)
Ian Lance Taylor31f58dc2013-01-28 08:54:15 -080017
18// Wrapper around the socket system call that marks the returned file
19// descriptor as nonblocking and close-on-exec.
Mikio Hara1d086e32014-03-04 09:28:09 +090020func sysSocket(family, sotype, proto int) (int, error) {
Mikio Hara29d1f3b2015-03-01 12:27:01 +090021 s, err := socketFunc(family, sotype|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, proto)
Mikio Hara1d086e32014-03-04 09:28:09 +090022 // 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.
Mikio Hara055ecb72015-04-21 21:20:15 +090027 switch err {
28 case nil:
29 return s, nil
30 default:
31 return -1, os.NewSyscallError("socket", err)
32 case syscall.EPROTONOSUPPORT, syscall.EINVAL:
Ian Lance Taylor31f58dc2013-01-28 08:54:15 -080033 }
34
35 // See ../syscall/exec_unix.go for description of ForkLock.
36 syscall.ForkLock.RLock()
Mikio Hara29d1f3b2015-03-01 12:27:01 +090037 s, err = socketFunc(family, sotype, proto)
Ian Lance Taylor31f58dc2013-01-28 08:54:15 -080038 if err == nil {
39 syscall.CloseOnExec(s)
40 }
41 syscall.ForkLock.RUnlock()
42 if err != nil {
Mikio Hara055ecb72015-04-21 21:20:15 +090043 return -1, os.NewSyscallError("socket", err)
Ian Lance Taylor31f58dc2013-01-28 08:54:15 -080044 }
45 if err = syscall.SetNonblock(s, true); err != nil {
Ian Lance Taylor3792db52017-02-10 14:59:38 -080046 poll.CloseFunc(s)
Mikio Hara055ecb72015-04-21 21:20:15 +090047 return -1, os.NewSyscallError("setnonblock", err)
Ian Lance Taylor31f58dc2013-01-28 08:54:15 -080048 }
49 return s, nil
50}