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 hurd illumos linux netbsd openbsd
6
7package socktest
8
9import "syscall"
10
11// Accept4 wraps syscall.Accept4.
12func (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}
43