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, _ := syscall.Getsockname(s)
27 rsa, _ := syscall.Getpeername(s)
28 switch lsa.(type) {
29 case *syscall.SockaddrInet4:
30 family = syscall.AF_INET
31 case *syscall.SockaddrInet6:
32 family = syscall.AF_INET6
33 case *syscall.SockaddrUnix:
34 family = syscall.AF_UNIX
35 default:
36 poll.CloseFunc(s)
37 return nil, syscall.EPROTONOSUPPORT
38 }
39 fd, err := newFD(s, family, sotype, "")
40 if err != nil {
41 poll.CloseFunc(s)
42 return nil, err
43 }
44 laddr := fd.addrFunc()(lsa)
45 raddr := fd.addrFunc()(rsa)
46 fd.net = laddr.Network()
47 if err := fd.init(); err != nil {
48 fd.Close()
49 return nil, err
50 }
51 fd.setAddr(laddr, raddr)
52 return fd, nil
53 }
54
55 func fileConn(f *os.File) (Conn, error) {
56 fd, err := newFileFD(f)
57 if err != nil {
58 return nil, err
59 }
60 switch fd.laddr.(type) {
61 case *TCPAddr:
62 return newTCPConn(fd, defaultTCPKeepAliveIdle, KeepAliveConfig{}, testPreHookSetKeepAlive, testHookSetKeepAlive), nil
63 case *UDPAddr:
64 return newUDPConn(fd), nil
65 case *IPAddr:
66 return newIPConn(fd), nil
67 case *UnixAddr:
68 return newUnixConn(fd), nil
69 }
70 fd.Close()
71 return nil, syscall.EINVAL
72 }
73
74 func fileListener(f *os.File) (Listener, error) {
75 fd, err := newFileFD(f)
76 if err != nil {
77 return nil, err
78 }
79 switch laddr := fd.laddr.(type) {
80 case *TCPAddr:
81 return &TCPListener{fd: fd}, nil
82 case *UnixAddr:
83 return &UnixListener{fd: fd, path: laddr.Name, unlink: false}, nil
84 }
85 fd.Close()
86 return nil, syscall.EINVAL
87 }
88
89 func filePacketConn(f *os.File) (PacketConn, error) {
90 fd, err := newFileFD(f)
91 if err != nil {
92 return nil, err
93 }
94 switch fd.laddr.(type) {
95 case *UDPAddr:
96 return newUDPConn(fd), nil
97 case *IPAddr:
98 return newIPConn(fd), nil
99 case *UnixAddr:
100 return newUnixConn(fd), nil
101 }
102 fd.Close()
103 return nil, syscall.EINVAL
104 }
105
View as plain text