...
1
2
3 package sysfs
4
5 import (
6 "net"
7 "syscall"
8
9 "github.com/tetratelabs/wazero/experimental/sys"
10 "github.com/tetratelabs/wazero/internal/fsapi"
11 socketapi "github.com/tetratelabs/wazero/internal/sock"
12 )
13
14
15 const MSG_PEEK = syscall.MSG_PEEK
16
17
18
19
20
21
22
23 func newTCPListenerFile(tl *net.TCPListener) socketapi.TCPSock {
24 conn, err := tl.File()
25 if err != nil {
26 panic(err)
27 }
28 fd := conn.Fd()
29
30
31
32
33 sysfd, err := syscall.Dup(int(fd))
34 if err != nil {
35 panic(err)
36 }
37 return &tcpListenerFile{fd: uintptr(sysfd), addr: tl.Addr().(*net.TCPAddr)}
38 }
39
40 var _ socketapi.TCPSock = (*tcpListenerFile)(nil)
41
42 type tcpListenerFile struct {
43 baseSockFile
44
45 fd uintptr
46 addr *net.TCPAddr
47 nonblock bool
48 }
49
50
51 func (f *tcpListenerFile) Accept() (socketapi.TCPConn, sys.Errno) {
52 nfd, _, err := syscall.Accept(int(f.fd))
53 errno := sys.UnwrapOSError(err)
54 if errno != 0 {
55 return nil, errno
56 }
57 return &tcpConnFile{fd: uintptr(nfd)}, 0
58 }
59
60
61 func (f *tcpListenerFile) Close() sys.Errno {
62 return sys.UnwrapOSError(syscall.Close(int(f.fd)))
63 }
64
65
66 func (f *tcpListenerFile) Addr() *net.TCPAddr {
67 return f.addr
68 }
69
70
71 func (f *tcpListenerFile) SetNonblock(enabled bool) sys.Errno {
72 f.nonblock = enabled
73 return sys.UnwrapOSError(setNonblock(f.fd, enabled))
74 }
75
76
77 func (f *tcpListenerFile) IsNonblock() bool {
78 return f.nonblock
79 }
80
81
82 func (f *tcpListenerFile) Poll(flag fsapi.Pflag, timeoutMillis int32) (ready bool, errno sys.Errno) {
83 return false, sys.ENOSYS
84 }
85
86 var _ socketapi.TCPConn = (*tcpConnFile)(nil)
87
88 type tcpConnFile struct {
89 baseSockFile
90
91 fd uintptr
92 nonblock bool
93
94
95 closed bool
96 }
97
98 func newTcpConn(tc *net.TCPConn) socketapi.TCPConn {
99 f, err := tc.File()
100 if err != nil {
101 panic(err)
102 }
103 return &tcpConnFile{fd: f.Fd()}
104 }
105
106
107 func (f *tcpConnFile) Read(buf []byte) (n int, errno sys.Errno) {
108 n, err := syscall.Read(int(f.fd), buf)
109 if err != nil {
110
111 errno = sys.UnwrapOSError(err)
112 errno = fileError(f, f.closed, errno)
113 }
114 return n, errno
115 }
116
117
118 func (f *tcpConnFile) Write(buf []byte) (n int, errno sys.Errno) {
119 n, err := syscall.Write(int(f.fd), buf)
120 if err != nil {
121
122 errno = sys.UnwrapOSError(err)
123 errno = fileError(f, f.closed, errno)
124 }
125 return n, errno
126 }
127
128
129 func (f *tcpConnFile) Recvfrom(p []byte, flags int) (n int, errno sys.Errno) {
130 if flags != MSG_PEEK {
131 errno = sys.EINVAL
132 return
133 }
134 n, _, recvfromErr := syscall.Recvfrom(int(f.fd), p, MSG_PEEK)
135 errno = sys.UnwrapOSError(recvfromErr)
136 return n, errno
137 }
138
139
140 func (f *tcpConnFile) Shutdown(how int) sys.Errno {
141 var err error
142 switch how {
143 case syscall.SHUT_RD, syscall.SHUT_WR:
144 err = syscall.Shutdown(int(f.fd), how)
145 case syscall.SHUT_RDWR:
146 return f.close()
147 default:
148 return sys.EINVAL
149 }
150 return sys.UnwrapOSError(err)
151 }
152
153
154 func (f *tcpConnFile) Close() sys.Errno {
155 return f.close()
156 }
157
158 func (f *tcpConnFile) close() sys.Errno {
159 if f.closed {
160 return 0
161 }
162 f.closed = true
163 return sys.UnwrapOSError(syscall.Shutdown(int(f.fd), syscall.SHUT_RDWR))
164 }
165
166
167 func (f *tcpConnFile) SetNonblock(enabled bool) (errno sys.Errno) {
168 f.nonblock = enabled
169 return sys.UnwrapOSError(setNonblock(f.fd, enabled))
170 }
171
172
173 func (f *tcpConnFile) IsNonblock() bool {
174 return f.nonblock
175 }
176
177
178 func (f *tcpConnFile) Poll(flag fsapi.Pflag, timeoutMillis int32) (ready bool, errno sys.Errno) {
179 return false, sys.ENOSYS
180 }
181
View as plain text