github.com/flyinox/gosm@v0.0.0-20171117061539-16768cb62077/src/net/internal/socktest/sys_cloexec.go (about)

     1  // Copyright 2015 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  // +build dragonfly freebsd linux
     6  
     7  package socktest
     8  
     9  import "syscall"
    10  
    11  // Accept4 wraps syscall.Accept4.
    12  func (sw *Switch) Accept4(s, flags int) (ns int, sa syscall.Sockaddr, err error) {
    13  	so := sw.sockso(s)
    14  	if so == nil {
    15  		return syscall.Accept4(s, flags)
    16  	}
    17  	sw.fmu.RLock()
    18  	f := sw.fltab[FilterAccept]
    19  	sw.fmu.RUnlock()
    20  
    21  	af, err := f.apply(so)
    22  	if err != nil {
    23  		return -1, nil, err
    24  	}
    25  	ns, sa, so.Err = syscall.Accept4(s, flags)
    26  	if err = af.apply(so); err != nil {
    27  		if so.Err == nil {
    28  			syscall.Close(ns)
    29  		}
    30  		return -1, nil, err
    31  	}
    32  
    33  	sw.smu.Lock()
    34  	defer sw.smu.Unlock()
    35  	if so.Err != nil {
    36  		sw.stats.getLocked(so.Cookie).AcceptFailed++
    37  		return -1, nil, so.Err
    38  	}
    39  	nso := sw.addLocked(ns, so.Cookie.Family(), so.Cookie.Type(), so.Cookie.Protocol())
    40  	sw.stats.getLocked(nso.Cookie).Accepted++
    41  	return ns, sa, nil
    42  }