[52/77] Use scalar_int_mode in extract/store_bit_field
[official-gcc.git] / libgo / go / net / unixsock.go
blobb25d492f5915bd2747a319bd8c270529e599e256
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package net
7 import (
8 "context"
9 "os"
10 "sync"
11 "syscall"
12 "time"
15 // UnixAddr represents the address of a Unix domain socket end point.
16 type UnixAddr struct {
17 Name string
18 Net string
21 // Network returns the address's network name, "unix", "unixgram" or
22 // "unixpacket".
23 func (a *UnixAddr) Network() string {
24 return a.Net
27 func (a *UnixAddr) String() string {
28 if a == nil {
29 return "<nil>"
31 return a.Name
34 func (a *UnixAddr) isWildcard() bool {
35 return a == nil || a.Name == ""
38 func (a *UnixAddr) opAddr() Addr {
39 if a == nil {
40 return nil
42 return a
45 // ResolveUnixAddr parses addr as a Unix domain socket address.
46 // The string net gives the network name, "unix", "unixgram" or
47 // "unixpacket".
48 func ResolveUnixAddr(net, addr string) (*UnixAddr, error) {
49 switch net {
50 case "unix", "unixgram", "unixpacket":
51 return &UnixAddr{Name: addr, Net: net}, nil
52 default:
53 return nil, UnknownNetworkError(net)
57 // UnixConn is an implementation of the Conn interface for connections
58 // to Unix domain sockets.
59 type UnixConn struct {
60 conn
63 // CloseRead shuts down the reading side of the Unix domain connection.
64 // Most callers should just use Close.
65 func (c *UnixConn) CloseRead() error {
66 if !c.ok() {
67 return syscall.EINVAL
69 if err := c.fd.closeRead(); err != nil {
70 return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
72 return nil
75 // CloseWrite shuts down the writing side of the Unix domain connection.
76 // Most callers should just use Close.
77 func (c *UnixConn) CloseWrite() error {
78 if !c.ok() {
79 return syscall.EINVAL
81 if err := c.fd.closeWrite(); err != nil {
82 return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
84 return nil
87 // ReadFromUnix reads a packet from c, copying the payload into b. It
88 // returns the number of bytes copied into b and the source address of
89 // the packet.
91 // ReadFromUnix can be made to time out and return an error with
92 // Timeout() == true after a fixed time limit; see SetDeadline and
93 // SetReadDeadline.
94 func (c *UnixConn) ReadFromUnix(b []byte) (int, *UnixAddr, error) {
95 if !c.ok() {
96 return 0, nil, syscall.EINVAL
98 n, addr, err := c.readFrom(b)
99 if err != nil {
100 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
102 return n, addr, err
105 // ReadFrom implements the PacketConn ReadFrom method.
106 func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error) {
107 if !c.ok() {
108 return 0, nil, syscall.EINVAL
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}
114 if addr == nil {
115 return n, nil, err
117 return n, addr, err
120 // ReadMsgUnix reads a packet from c, copying the payload into b and
121 // the associated out-of-band data into oob. It returns the number of
122 // bytes copied into b, the number of bytes copied into oob, the flags
123 // that were set on the packet, and the source address of the packet.
125 // Note that if len(b) == 0 and len(oob) > 0, this function will still
126 // read (and discard) 1 byte from the connection.
127 func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) {
128 if !c.ok() {
129 return 0, 0, 0, nil, syscall.EINVAL
131 n, oobn, flags, addr, err = c.readMsg(b, oob)
132 if err != nil {
133 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
135 return
138 // WriteToUnix writes a packet to addr via c, copying the payload from b.
140 // WriteToUnix can be made to time out and return an error with
141 // Timeout() == true after a fixed time limit; see SetDeadline and
142 // SetWriteDeadline. On packet-oriented connections, write timeouts
143 // are rare.
144 func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (int, error) {
145 if !c.ok() {
146 return 0, syscall.EINVAL
148 n, err := c.writeTo(b, addr)
149 if err != nil {
150 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
152 return n, err
155 // WriteTo implements the PacketConn WriteTo method.
156 func (c *UnixConn) WriteTo(b []byte, addr Addr) (int, error) {
157 if !c.ok() {
158 return 0, syscall.EINVAL
160 a, ok := addr.(*UnixAddr)
161 if !ok {
162 return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
164 n, err := c.writeTo(b, a)
165 if err != nil {
166 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: a.opAddr(), Err: err}
168 return n, err
171 // WriteMsgUnix writes a packet to addr via c, copying the payload
172 // from b and the associated out-of-band data from oob. It returns
173 // the number of payload and out-of-band bytes written.
175 // Note that if len(b) == 0 and len(oob) > 0, this function will still
176 // write 1 byte to the connection.
177 func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) {
178 if !c.ok() {
179 return 0, 0, syscall.EINVAL
181 n, oobn, err = c.writeMsg(b, oob, addr)
182 if err != nil {
183 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
185 return
188 func newUnixConn(fd *netFD) *UnixConn { return &UnixConn{conn{fd}} }
190 // DialUnix connects to the remote address raddr on the network net,
191 // which must be "unix", "unixgram" or "unixpacket". If laddr is not
192 // nil, it is used as the local address for the connection.
193 func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) {
194 switch net {
195 case "unix", "unixgram", "unixpacket":
196 default:
197 return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(net)}
199 c, err := dialUnix(context.Background(), net, laddr, raddr)
200 if err != nil {
201 return nil, &OpError{Op: "dial", Net: net, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
203 return c, nil
206 // UnixListener is a Unix domain socket listener. Clients should
207 // typically use variables of type Listener instead of assuming Unix
208 // domain sockets.
209 type UnixListener struct {
210 fd *netFD
211 path string
212 unlink bool
213 unlinkOnce sync.Once
216 func (ln *UnixListener) ok() bool { return ln != nil && ln.fd != nil }
218 // AcceptUnix accepts the next incoming call and returns the new
219 // connection.
220 func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
221 if !l.ok() {
222 return nil, syscall.EINVAL
224 c, err := l.accept()
225 if err != nil {
226 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
228 return c, nil
231 // Accept implements the Accept method in the Listener interface.
232 // Returned connections will be of type *UnixConn.
233 func (l *UnixListener) Accept() (Conn, error) {
234 if !l.ok() {
235 return nil, syscall.EINVAL
237 c, err := l.accept()
238 if err != nil {
239 return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
241 return c, nil
244 // Close stops listening on the Unix address. Already accepted
245 // connections are not closed.
246 func (l *UnixListener) Close() error {
247 if !l.ok() {
248 return syscall.EINVAL
250 if err := l.close(); err != nil {
251 return &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
253 return nil
256 // Addr returns the listener's network address.
257 // The Addr returned is shared by all invocations of Addr, so
258 // do not modify it.
259 func (l *UnixListener) Addr() Addr { return l.fd.laddr }
261 // SetDeadline sets the deadline associated with the listener.
262 // A zero time value disables the deadline.
263 func (l *UnixListener) SetDeadline(t time.Time) error {
264 if !l.ok() {
265 return syscall.EINVAL
267 if err := l.fd.setDeadline(t); err != nil {
268 return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
270 return nil
273 // File returns a copy of the underlying os.File, set to blocking
274 // mode. It is the caller's responsibility to close f when finished.
275 // Closing l does not affect f, and closing f does not affect l.
277 // The returned os.File's file descriptor is different from the
278 // connection's. Attempting to change properties of the original
279 // using this duplicate may or may not have the desired effect.
280 func (l *UnixListener) File() (f *os.File, err error) {
281 if !l.ok() {
282 return nil, syscall.EINVAL
284 f, err = l.file()
285 if err != nil {
286 err = &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
288 return
291 // ListenUnix announces on the Unix domain socket laddr and returns a
292 // Unix listener. The network net must be "unix" or "unixpacket".
293 func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) {
294 switch net {
295 case "unix", "unixpacket":
296 default:
297 return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(net)}
299 if laddr == nil {
300 return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: errMissingAddress}
302 ln, err := listenUnix(context.Background(), net, laddr)
303 if err != nil {
304 return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: err}
306 return ln, nil
309 // ListenUnixgram listens for incoming Unix datagram packets addressed
310 // to the local address laddr. The network net must be "unixgram".
311 // The returned connection's ReadFrom and WriteTo methods can be used
312 // to receive and send packets with per-packet addressing.
313 func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error) {
314 switch net {
315 case "unixgram":
316 default:
317 return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(net)}
319 if laddr == nil {
320 return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: nil, Err: errMissingAddress}
322 c, err := listenUnixgram(context.Background(), net, laddr)
323 if err != nil {
324 return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr.opAddr(), Err: err}
326 return c, nil