Source file
src/net/unixsock.go
1
2
3
4
5 package net
6
7 import (
8 "context"
9 "os"
10 "sync"
11 "syscall"
12 "time"
13 )
14
15
16
17
18
19
20
21
22 type UnixAddr struct {
23 Name string
24 Net string
25 }
26
27
28
29 func (a *UnixAddr) Network() string {
30 return a.Net
31 }
32
33 func (a *UnixAddr) String() string {
34 if a == nil {
35 return "<nil>"
36 }
37 return a.Name
38 }
39
40 func (a *UnixAddr) isWildcard() bool {
41 return a == nil || a.Name == ""
42 }
43
44 func (a *UnixAddr) opAddr() Addr {
45 if a == nil {
46 return nil
47 }
48 return a
49 }
50
51
52
53
54
55
56
57 func ResolveUnixAddr(network, address string) (*UnixAddr, error) {
58 switch network {
59 case "unix", "unixgram", "unixpacket":
60 return &UnixAddr{Name: address, Net: network}, nil
61 default:
62 return nil, UnknownNetworkError(network)
63 }
64 }
65
66
67
68 type UnixConn struct {
69 conn
70 }
71
72
73
74 func (c *UnixConn) SyscallConn() (syscall.RawConn, error) {
75 if !c.ok() {
76 return nil, syscall.EINVAL
77 }
78 return newRawConn(c.fd), nil
79 }
80
81
82
83 func (c *UnixConn) CloseRead() error {
84 if !c.ok() {
85 return syscall.EINVAL
86 }
87 if err := c.fd.closeRead(); err != nil {
88 return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
89 }
90 return nil
91 }
92
93
94
95 func (c *UnixConn) CloseWrite() error {
96 if !c.ok() {
97 return syscall.EINVAL
98 }
99 if err := c.fd.closeWrite(); err != nil {
100 return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
101 }
102 return nil
103 }
104
105
106 func (c *UnixConn) ReadFromUnix(b []byte) (int, *UnixAddr, error) {
107 if !c.ok() {
108 return 0, nil, syscall.EINVAL
109 }
110 n, addr, err := c.readFrom(b)
111 if err != nil {
112 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
113 }
114 return n, addr, err
115 }
116
117
118 func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error) {
119 if !c.ok() {
120 return 0, nil, syscall.EINVAL
121 }
122 n, addr, err := c.readFrom(b)
123 if err != nil {
124 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
125 }
126 if addr == nil {
127 return n, nil, err
128 }
129 return n, addr, err
130 }
131
132
133
134
135
136
137
138
139 func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) {
140 if !c.ok() {
141 return 0, 0, 0, nil, syscall.EINVAL
142 }
143 n, oobn, flags, addr, err = c.readMsg(b, oob)
144 if err != nil {
145 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
146 }
147 return
148 }
149
150
151 func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (int, error) {
152 if !c.ok() {
153 return 0, syscall.EINVAL
154 }
155 n, err := c.writeTo(b, addr)
156 if err != nil {
157 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
158 }
159 return n, err
160 }
161
162
163 func (c *UnixConn) WriteTo(b []byte, addr Addr) (int, error) {
164 if !c.ok() {
165 return 0, syscall.EINVAL
166 }
167 a, ok := addr.(*UnixAddr)
168 if !ok {
169 return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
170 }
171 n, err := c.writeTo(b, a)
172 if err != nil {
173 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: a.opAddr(), Err: err}
174 }
175 return n, err
176 }
177
178
179
180
181
182
183
184 func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) {
185 if !c.ok() {
186 return 0, 0, syscall.EINVAL
187 }
188 n, oobn, err = c.writeMsg(b, oob, addr)
189 if err != nil {
190 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
191 }
192 return
193 }
194
195 func newUnixConn(fd *netFD) *UnixConn { return &UnixConn{conn{fd}} }
196
197
198
199
200
201
202
203 func DialUnix(network string, laddr, raddr *UnixAddr) (*UnixConn, error) {
204 return dialUnix(context.Background(), nil, network, laddr, raddr)
205 }
206
207 func dialUnix(ctx context.Context, dialer *Dialer, network string, laddr, raddr *UnixAddr) (*UnixConn, error) {
208 switch network {
209 case "unix", "unixgram", "unixpacket":
210 default:
211 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
212 }
213 sd := &sysDialer{network: network, address: raddr.String()}
214 if dialer != nil {
215 sd.Dialer = *dialer
216 }
217 c, err := sd.dialUnix(ctx, laddr, raddr)
218 if err != nil {
219 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
220 }
221 return c, nil
222 }
223
224
225
226
227 type UnixListener struct {
228 fd *netFD
229 path string
230 unlink bool
231 unlinkOnce sync.Once
232 }
233
234 func (ln *UnixListener) ok() bool { return ln != nil && ln.fd != nil }
235
236
237
238
239
240
241 func (l *UnixListener) SyscallConn() (syscall.RawConn, error) {
242 if !l.ok() {
243 return nil, syscall.EINVAL
244 }
245 return newRawListener(l.fd), nil
246 }
247
248
249
250 func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
251 if !l.ok() {
252 return nil, syscall.EINVAL
253 }
254 c, err := l.accept()
255 if err != nil {
256 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
257 }
258 return c, nil
259 }
260
261
262
263 func (l *UnixListener) Accept() (Conn, error) {
264 if !l.ok() {
265 return nil, syscall.EINVAL
266 }
267 c, err := l.accept()
268 if err != nil {
269 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
270 }
271 return c, nil
272 }
273
274
275
276 func (l *UnixListener) Close() error {
277 if !l.ok() {
278 return syscall.EINVAL
279 }
280 if err := l.close(); err != nil {
281 return &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
282 }
283 return nil
284 }
285
286
287
288
289 func (l *UnixListener) Addr() Addr { return l.fd.laddr }
290
291
292
293 func (l *UnixListener) SetDeadline(t time.Time) error {
294 if !l.ok() {
295 return syscall.EINVAL
296 }
297 return l.fd.SetDeadline(t)
298 }
299
300
301
302
303
304
305
306
307
308
309
310 func (l *UnixListener) File() (f *os.File, err error) {
311 if !l.ok() {
312 return nil, syscall.EINVAL
313 }
314 f, err = l.file()
315 if err != nil {
316 err = &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
317 }
318 return
319 }
320
321
322
323
324 func ListenUnix(network string, laddr *UnixAddr) (*UnixListener, error) {
325 switch network {
326 case "unix", "unixpacket":
327 default:
328 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
329 }
330 if laddr == nil {
331 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: errMissingAddress}
332 }
333 sl := &sysListener{network: network, address: laddr.String()}
334 ln, err := sl.listenUnix(context.Background(), laddr)
335 if err != nil {
336 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
337 }
338 return ln, nil
339 }
340
341
342
343
344 func ListenUnixgram(network string, laddr *UnixAddr) (*UnixConn, error) {
345 switch network {
346 case "unixgram":
347 default:
348 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
349 }
350 if laddr == nil {
351 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: errMissingAddress}
352 }
353 sl := &sysListener{network: network, address: laddr.String()}
354 c, err := sl.listenUnixgram(context.Background(), laddr)
355 if err != nil {
356 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
357 }
358 return c, nil
359 }
360
View as plain text