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