...

Source file src/pkg/net/sock_cloexec.go

     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 netbsd openbsd
     9	
    10	package net
    11	
    12	import (
    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.
    20	func 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	

View as plain text