1// Copyright 2024 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 sysSocket for platforms that provide a fast path for 6// setting SetNonblock and CloseOnExec, but don't necessarily support it. 7// Support for SOCK_* flags as part of the type parameter was added to Oracle 8// Solaris in the 11.4 release. Thus, on releases prior to 11.4, we fall back 9// to the combination of socket(3c) and fcntl(2). 10 11package net 12 13import ( 14 "internal/poll" 15 "internal/syscall/unix" 16 "os" 17 "syscall" 18) 19 20// Wrapper around the socket system call that marks the returned file 21// descriptor as nonblocking and close-on-exec. 22func sysSocket(family, sotype, proto int) (int, error) { 23 // Perform a cheap test and try the fast path first. 24 if unix.SupportSockNonblockCloexec() { 25 s, err := socketFunc(family, sotype|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, proto) 26 if err != nil { 27 return -1, os.NewSyscallError("socket", err) 28 } 29 return s, nil 30 } 31 32 // See ../syscall/exec_unix.go for description of ForkLock. 33 syscall.ForkLock.RLock() 34 s, err := socketFunc(family, sotype, proto) 35 if err == nil { 36 syscall.CloseOnExec(s) 37 } 38 syscall.ForkLock.RUnlock() 39 if err != nil { 40 return -1, os.NewSyscallError("socket", err) 41 } 42 if err = syscall.SetNonblock(s, true); err != nil { 43 poll.CloseFunc(s) 44 return -1, os.NewSyscallError("setnonblock", err) 45 } 46 return s, nil 47} 48