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