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
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)
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 switch network {
205 case "unix", "unixgram", "unixpacket":
206 default:
207 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
208 }
209 sd := &sysDialer{network: network, address: raddr.String()}
210 c, err := sd.dialUnix(context.Background(), laddr, raddr)
211 if err != nil {
212 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
213 }
214 return c, nil
215 }
216
217
218
219
220 type UnixListener struct {
221 fd *netFD
222 path string
223 unlink bool
224 unlinkOnce sync.Once
225 }
226
227 func (ln *UnixListener) ok() bool { return ln != nil && ln.fd != nil }
228
229
230
231
232
233
234 func (l *UnixListener) SyscallConn() (syscall.RawConn, error) {
235 if !l.ok() {
236 return nil, syscall.EINVAL
237 }
238 return newRawListener(l.fd)
239 }
240
241
242
243 func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
244 if !l.ok() {
245 return nil, syscall.EINVAL
246 }
247 c, err := l.accept()
248 if err != nil {
249 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
250 }
251 return c, nil
252 }
253
254
255
256 func (l *UnixListener) Accept() (Conn, error) {
257 if !l.ok() {
258 return nil, syscall.EINVAL
259 }
260 c, err := l.accept()
261 if err != nil {
262 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
263 }
264 return c, nil
265 }
266
267
268
269 func (l *UnixListener) Close() error {
270 if !l.ok() {
271 return syscall.EINVAL
272 }
273 if err := l.close(); err != nil {
274 return &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
275 }
276 return nil
277 }
278
279
280
281
282 func (l *UnixListener) Addr() Addr { return l.fd.laddr }
283
284
285
286 func (l *UnixListener) SetDeadline(t time.Time) error {
287 if !l.ok() {
288 return syscall.EINVAL
289 }
290 if err := l.fd.pfd.SetDeadline(t); err != nil {
291 return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
292 }
293 return nil
294 }
295
296
297
298
299
300
301
302
303 func (l *UnixListener) File() (f *os.File, err error) {
304 if !l.ok() {
305 return nil, syscall.EINVAL
306 }
307 f, err = l.file()
308 if err != nil {
309 err = &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
310 }
311 return
312 }
313
314
315
316
317 func ListenUnix(network string, laddr *UnixAddr) (*UnixListener, error) {
318 switch network {
319 case "unix", "unixpacket":
320 default:
321 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
322 }
323 if laddr == nil {
324 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: errMissingAddress}
325 }
326 sl := &sysListener{network: network, address: laddr.String()}
327 ln, err := sl.listenUnix(context.Background(), laddr)
328 if err != nil {
329 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
330 }
331 return ln, nil
332 }
333
334
335
336
337 func ListenUnixgram(network string, laddr *UnixAddr) (*UnixConn, error) {
338 switch network {
339 case "unixgram":
340 default:
341 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
342 }
343 if laddr == nil {
344 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: errMissingAddress}
345 }
346 sl := &sysListener{network: network, address: laddr.String()}
347 c, err := sl.listenUnixgram(context.Background(), laddr)
348 if err != nil {
349 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
350 }
351 return c, nil
352 }
353
View as plain text