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