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