1 // Copyright 2011 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.
5 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
15 func dupSocket(f
*os
.File
) (int, error
) {
16 s
, err
:= dupCloseOnExec(int(f
.Fd()))
20 if err
:= syscall
.SetNonblock(s
, true); err
!= nil {
22 return -1, os
.NewSyscallError("setnonblock", err
)
27 func newFileFD(f
*os
.File
) (*netFD
, error
) {
28 s
, err
:= dupSocket(f
)
32 family
:= syscall
.AF_UNSPEC
33 sotype
, err
:= syscall
.GetsockoptInt(s
, syscall
.SOL_SOCKET
, syscall
.SO_TYPE
)
36 return nil, os
.NewSyscallError("getsockopt", err
)
38 lsa
, _
:= syscall
.Getsockname(s
)
39 rsa
, _
:= syscall
.Getpeername(s
)
41 case *syscall
.SockaddrInet4
:
42 family
= syscall
.AF_INET
43 case *syscall
.SockaddrInet6
:
44 family
= syscall
.AF_INET6
45 case *syscall
.SockaddrUnix
:
46 family
= syscall
.AF_UNIX
49 return nil, syscall
.EPROTONOSUPPORT
51 fd
, err
:= newFD(s
, family
, sotype
, "")
56 laddr
:= fd
.addrFunc()(lsa
)
57 raddr
:= fd
.addrFunc()(rsa
)
58 fd
.net
= laddr
.Network()
59 if err
:= fd
.init(); err
!= nil {
63 fd
.setAddr(laddr
, raddr
)
67 func fileConn(f
*os
.File
) (Conn
, error
) {
68 fd
, err
:= newFileFD(f
)
72 switch fd
.laddr
.(type) {
74 return newTCPConn(fd
), nil
76 return newUDPConn(fd
), nil
78 return newIPConn(fd
), nil
80 return newUnixConn(fd
), nil
83 return nil, syscall
.EINVAL
86 func fileListener(f
*os
.File
) (Listener
, error
) {
87 fd
, err
:= newFileFD(f
)
91 switch laddr
:= fd
.laddr
.(type) {
93 return &TCPListener
{fd
}, nil
95 return &UnixListener
{fd
: fd
, path
: laddr
.Name
, unlink
: false}, nil
98 return nil, syscall
.EINVAL
101 func filePacketConn(f
*os
.File
) (PacketConn
, error
) {
102 fd
, err
:= newFileFD(f
)
106 switch fd
.laddr
.(type) {
108 return newUDPConn(fd
), nil
110 return newIPConn(fd
), nil
112 return newUnixConn(fd
), nil
115 return nil, syscall
.EINVAL