Source file
src/net/file_posix.go
1
2
3
4
5
6
7 package net
8
9 import (
10 "internal/poll"
11 "os"
12 "syscall"
13 )
14
15 func newFileFD(f *os.File) (*netFD, error) {
16 s, err := dupFileSocket(f)
17 if err != nil {
18 return nil, err
19 }
20 family := syscall.AF_UNSPEC
21 sotype, err := syscall.GetsockoptInt(s, syscall.SOL_SOCKET, _SO_TYPE)
22 if err != nil {
23 poll.CloseFunc(s)
24 return nil, os.NewSyscallError("getsockopt", err)
25 }
26 lsa, err := syscall.Getsockname(s)
27 if err != nil {
28 poll.CloseFunc(s)
29 return nil, os.NewSyscallError("getsockname", err)
30 }
31 rsa, _ := syscall.Getpeername(s)
32 switch lsa.(type) {
33 case *syscall.SockaddrInet4:
34 family = syscall.AF_INET
35 case *syscall.SockaddrInet6:
36 family = syscall.AF_INET6
37 case *syscall.SockaddrUnix:
38 family = syscall.AF_UNIX
39 default:
40 poll.CloseFunc(s)
41 return nil, syscall.EPROTONOSUPPORT
42 }
43 fd, err := newFD(s, family, sotype, "")
44 if err != nil {
45 poll.CloseFunc(s)
46 return nil, err
47 }
48 laddr := fd.addrFunc()(lsa)
49 raddr := fd.addrFunc()(rsa)
50 fd.net = laddr.Network()
51 if err := fd.init(); err != nil {
52 fd.Close()
53 return nil, err
54 }
55 fd.setAddr(laddr, raddr)
56 return fd, nil
57 }
58
59 func fileConn(f *os.File) (Conn, error) {
60 fd, err := newFileFD(f)
61 if err != nil {
62 return nil, err
63 }
64 switch fd.laddr.(type) {
65 case *TCPAddr:
66 return newTCPConn(fd, defaultTCPKeepAliveIdle, KeepAliveConfig{}, testPreHookSetKeepAlive, testHookSetKeepAlive), nil
67 case *UDPAddr:
68 return newUDPConn(fd), nil
69 case *IPAddr:
70 return newIPConn(fd), nil
71 case *UnixAddr:
72 return newUnixConn(fd), nil
73 }
74 fd.Close()
75 return nil, syscall.EINVAL
76 }
77
78 func fileListener(f *os.File) (Listener, error) {
79 fd, err := newFileFD(f)
80 if err != nil {
81 return nil, err
82 }
83 switch laddr := fd.laddr.(type) {
84 case *TCPAddr:
85 return &TCPListener{fd: fd}, nil
86 case *UnixAddr:
87 return &UnixListener{fd: fd, path: laddr.Name, unlink: false}, nil
88 }
89 fd.Close()
90 return nil, syscall.EINVAL
91 }
92
93 func filePacketConn(f *os.File) (PacketConn, error) {
94 fd, err := newFileFD(f)
95 if err != nil {
96 return nil, err
97 }
98 switch fd.laddr.(type) {
99 case *UDPAddr:
100 return newUDPConn(fd), nil
101 case *IPAddr:
102 return newIPConn(fd), nil
103 case *UnixAddr:
104 return newUnixConn(fd), nil
105 }
106 fd.Close()
107 return nil, syscall.EINVAL
108 }
109
View as plain text