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 sysSocket and accept for platforms that
6// provide a fast path for setting SetNonblock and CloseOnExec.
7
8// +build dragonfly freebsd linux
9
10package net
11
12import (
13	"internal/poll"
14	"os"
15	"syscall"
16)
17
18// Wrapper around the socket system call that marks the returned file
19// descriptor as nonblocking and close-on-exec.
20func sysSocket(family, sotype, proto int) (int, error) {
21	s, err := socketFunc(family, sotype|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, proto)
22	// 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.
27	switch err {
28	case nil:
29		return s, nil
30	default:
31		return -1, os.NewSyscallError("socket", err)
32	case syscall.EPROTONOSUPPORT, syscall.EINVAL:
33	}
34
35	// See ../syscall/exec_unix.go for description of ForkLock.
36	syscall.ForkLock.RLock()
37	s, err = socketFunc(family, sotype, proto)
38	if err == nil {
39		syscall.CloseOnExec(s)
40	}
41	syscall.ForkLock.RUnlock()
42	if err != nil {
43		return -1, os.NewSyscallError("socket", err)
44	}
45	if err = syscall.SetNonblock(s, true); err != nil {
46		poll.CloseFunc(s)
47		return -1, os.NewSyscallError("setnonblock", err)
48	}
49	return s, nil
50}
51