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.
15 // UnixAddr represents the address of a Unix domain socket end point.
16 type UnixAddr
struct {
21 // Network returns the address's network name, "unix", "unixgram" or
23 func (a
*UnixAddr
) Network() string {
27 func (a
*UnixAddr
) String() string {
34 func (a
*UnixAddr
) isWildcard() bool {
35 return a
== nil || a
.Name
== ""
38 func (a
*UnixAddr
) opAddr() Addr
{
45 // ResolveUnixAddr parses addr as a Unix domain socket address.
46 // The string net gives the network name, "unix", "unixgram" or
48 func ResolveUnixAddr(net
, addr
string) (*UnixAddr
, error
) {
50 case "unix", "unixgram", "unixpacket":
51 return &UnixAddr
{Name
: addr
, Net
: net
}, nil
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 {
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
{
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
}
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
{
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
}
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
91 // ReadFromUnix can be made to time out and return an error with
92 // Timeout() == true after a fixed time limit; see SetDeadline and
94 func (c
*UnixConn
) ReadFromUnix(b
[]byte) (int, *UnixAddr
, error
) {
96 return 0, nil, syscall
.EINVAL
98 n
, addr
, err
:= c
.readFrom(b
)
100 err
= &OpError
{Op
: "read", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
105 // ReadFrom implements the PacketConn ReadFrom method.
106 func (c
*UnixConn
) ReadFrom(b
[]byte) (int, Addr
, error
) {
108 return 0, nil, syscall
.EINVAL
110 n
, addr
, err
:= c
.readFrom(b
)
112 err
= &OpError
{Op
: "read", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: 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
) {
129 return 0, 0, 0, nil, syscall
.EINVAL
131 n
, oobn
, flags
, addr
, err
= c
.readMsg(b
, oob
)
133 err
= &OpError
{Op
: "read", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
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
144 func (c
*UnixConn
) WriteToUnix(b
[]byte, addr
*UnixAddr
) (int, error
) {
146 return 0, syscall
.EINVAL
148 n
, err
:= c
.writeTo(b
, addr
)
150 err
= &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: addr
.opAddr(), Err
: err
}
155 // WriteTo implements the PacketConn WriteTo method.
156 func (c
*UnixConn
) WriteTo(b
[]byte, addr Addr
) (int, error
) {
158 return 0, syscall
.EINVAL
160 a
, ok
:= addr
.(*UnixAddr
)
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
)
166 err
= &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: a
.opAddr(), Err
: 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
) {
179 return 0, 0, syscall
.EINVAL
181 n
, oobn
, err
= c
.writeMsg(b
, oob
, addr
)
183 err
= &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: addr
.opAddr(), Err
: err
}
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
) {
195 case "unix", "unixgram", "unixpacket":
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
)
201 return nil, &OpError
{Op
: "dial", Net
: net
, Source
: laddr
.opAddr(), Addr
: raddr
.opAddr(), Err
: err
}
206 // UnixListener is a Unix domain socket listener. Clients should
207 // typically use variables of type Listener instead of assuming Unix
209 type UnixListener
struct {
216 func (ln
*UnixListener
) ok() bool { return ln
!= nil && ln
.fd
!= nil }
218 // AcceptUnix accepts the next incoming call and returns the new
220 func (l
*UnixListener
) AcceptUnix() (*UnixConn
, error
) {
222 return nil, syscall
.EINVAL
226 return nil, &OpError
{Op
: "accept", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
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
) {
235 return nil, syscall
.EINVAL
239 return nil, &OpError
{Op
: "accept", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
244 // Close stops listening on the Unix address. Already accepted
245 // connections are not closed.
246 func (l
*UnixListener
) Close() error
{
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
}
256 // Addr returns the listener's network address.
257 // The Addr returned is shared by all invocations of Addr, so
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
{
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
}
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
) {
282 return nil, syscall
.EINVAL
286 err
= &OpError
{Op
: "file", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
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
) {
295 case "unix", "unixpacket":
297 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: laddr
.opAddr(), Err
: UnknownNetworkError(net
)}
300 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: laddr
.opAddr(), Err
: errMissingAddress
}
302 ln
, err
:= listenUnix(context
.Background(), net
, laddr
)
304 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: laddr
.opAddr(), Err
: err
}
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
) {
317 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: laddr
.opAddr(), Err
: UnknownNetworkError(net
)}
320 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: nil, Err
: errMissingAddress
}
322 c
, err
:= listenUnixgram(context
.Background(), net
, laddr
)
324 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: laddr
.opAddr(), Err
: err
}