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 // BUG(mikio): On JS and Plan 9, methods and functions related
16 // to UnixConn and UnixListener are not implemented.
18 // BUG(mikio): On Windows, methods and functions related to UnixConn
19 // and UnixListener don't work for "unixgram" and "unixpacket".
21 // UnixAddr represents the address of a Unix domain socket end point.
22 type UnixAddr
struct {
27 // Network returns the address's network name, "unix", "unixgram" or
29 func (a
*UnixAddr
) Network() string {
33 func (a
*UnixAddr
) String() string {
40 func (a
*UnixAddr
) isWildcard() bool {
41 return a
== nil || a
.Name
== ""
44 func (a
*UnixAddr
) opAddr() Addr
{
51 // ResolveUnixAddr returns an address of Unix domain socket end point.
53 // The network must be a Unix network name.
55 // See func Dial for a description of the network and address
57 func ResolveUnixAddr(network
, address
string) (*UnixAddr
, error
) {
59 case "unix", "unixgram", "unixpacket":
60 return &UnixAddr
{Name
: address
, Net
: network
}, nil
62 return nil, UnknownNetworkError(network
)
66 // UnixConn is an implementation of the Conn interface for connections
67 // to Unix domain sockets.
68 type UnixConn
struct {
72 // SyscallConn returns a raw network connection.
73 // This implements the syscall.Conn interface.
74 func (c
*UnixConn
) SyscallConn() (syscall
.RawConn
, error
) {
76 return nil, syscall
.EINVAL
78 return newRawConn(c
.fd
)
81 // CloseRead shuts down the reading side of the Unix domain connection.
82 // Most callers should just use Close.
83 func (c
*UnixConn
) CloseRead() error
{
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
}
93 // CloseWrite shuts down the writing side of the Unix domain connection.
94 // Most callers should just use Close.
95 func (c
*UnixConn
) CloseWrite() error
{
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
}
105 // ReadFromUnix acts like ReadFrom but returns a UnixAddr.
106 func (c
*UnixConn
) ReadFromUnix(b
[]byte) (int, *UnixAddr
, 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
}
117 // ReadFrom implements the PacketConn ReadFrom method.
118 func (c
*UnixConn
) ReadFrom(b
[]byte) (int, Addr
, error
) {
120 return 0, nil, syscall
.EINVAL
122 n
, addr
, err
:= c
.readFrom(b
)
124 err
= &OpError
{Op
: "read", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
132 // ReadMsgUnix reads a message from c, copying the payload into b and
133 // the associated out-of-band data into oob. It returns the number of
134 // bytes copied into b, the number of bytes copied into oob, the flags
135 // that were set on the message and the source address of the message.
137 // Note that if len(b) == 0 and len(oob) > 0, this function will still
138 // read (and discard) 1 byte from the connection.
139 func (c
*UnixConn
) ReadMsgUnix(b
, oob
[]byte) (n
, oobn
, flags
int, addr
*UnixAddr
, err error
) {
141 return 0, 0, 0, nil, syscall
.EINVAL
143 n
, oobn
, flags
, addr
, err
= c
.readMsg(b
, oob
)
145 err
= &OpError
{Op
: "read", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
150 // WriteToUnix acts like WriteTo but takes a UnixAddr.
151 func (c
*UnixConn
) WriteToUnix(b
[]byte, addr
*UnixAddr
) (int, error
) {
153 return 0, syscall
.EINVAL
155 n
, err
:= c
.writeTo(b
, addr
)
157 err
= &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: addr
.opAddr(), Err
: err
}
162 // WriteTo implements the PacketConn WriteTo method.
163 func (c
*UnixConn
) WriteTo(b
[]byte, addr Addr
) (int, error
) {
165 return 0, syscall
.EINVAL
167 a
, ok
:= addr
.(*UnixAddr
)
169 return 0, &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: addr
, Err
: syscall
.EINVAL
}
171 n
, err
:= c
.writeTo(b
, a
)
173 err
= &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: a
.opAddr(), Err
: err
}
178 // WriteMsgUnix writes a message to addr via c, copying the payload
179 // from b and the associated out-of-band data from oob. It returns the
180 // number of payload and out-of-band bytes written.
182 // Note that if len(b) == 0 and len(oob) > 0, this function will still
183 // write 1 byte to the connection.
184 func (c
*UnixConn
) WriteMsgUnix(b
, oob
[]byte, addr
*UnixAddr
) (n
, oobn
int, err error
) {
186 return 0, 0, syscall
.EINVAL
188 n
, oobn
, err
= c
.writeMsg(b
, oob
, addr
)
190 err
= &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: addr
.opAddr(), Err
: err
}
195 func newUnixConn(fd
*netFD
) *UnixConn
{ return &UnixConn
{conn
{fd
}} }
197 // DialUnix acts like Dial for Unix networks.
199 // The network must be a Unix network name; see func Dial for details.
201 // If laddr is non-nil, it is used as the local address for the
203 func DialUnix(network
string, laddr
, raddr
*UnixAddr
) (*UnixConn
, error
) {
205 case "unix", "unixgram", "unixpacket":
207 return nil, &OpError
{Op
: "dial", Net
: network
, Source
: laddr
.opAddr(), Addr
: raddr
.opAddr(), Err
: UnknownNetworkError(network
)}
209 sd
:= &sysDialer
{network
: network
, address
: raddr
.String()}
210 c
, err
:= sd
.dialUnix(context
.Background(), laddr
, raddr
)
212 return nil, &OpError
{Op
: "dial", Net
: network
, Source
: laddr
.opAddr(), Addr
: raddr
.opAddr(), Err
: err
}
217 // UnixListener is a Unix domain socket listener. Clients should
218 // typically use variables of type Listener instead of assuming Unix
220 type UnixListener
struct {
227 func (ln
*UnixListener
) ok() bool { return ln
!= nil && ln
.fd
!= nil }
229 // SyscallConn returns a raw network connection.
230 // This implements the syscall.Conn interface.
232 // The returned RawConn only supports calling Control. Read and
233 // Write return an error.
234 func (l
*UnixListener
) SyscallConn() (syscall
.RawConn
, error
) {
236 return nil, syscall
.EINVAL
238 return newRawListener(l
.fd
)
241 // AcceptUnix accepts the next incoming call and returns the new
243 func (l
*UnixListener
) AcceptUnix() (*UnixConn
, error
) {
245 return nil, syscall
.EINVAL
249 return nil, &OpError
{Op
: "accept", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
254 // Accept implements the Accept method in the Listener interface.
255 // Returned connections will be of type *UnixConn.
256 func (l
*UnixListener
) Accept() (Conn
, error
) {
258 return nil, syscall
.EINVAL
262 return nil, &OpError
{Op
: "accept", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
267 // Close stops listening on the Unix address. Already accepted
268 // connections are not closed.
269 func (l
*UnixListener
) Close() error
{
271 return syscall
.EINVAL
273 if err
:= l
.close(); err
!= nil {
274 return &OpError
{Op
: "close", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
279 // Addr returns the listener's network address.
280 // The Addr returned is shared by all invocations of Addr, so
282 func (l
*UnixListener
) Addr() Addr
{ return l
.fd
.laddr
}
284 // SetDeadline sets the deadline associated with the listener.
285 // A zero time value disables the deadline.
286 func (l
*UnixListener
) SetDeadline(t time
.Time
) error
{
288 return syscall
.EINVAL
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
}
296 // File returns a copy of the underlying os.File.
297 // It is the caller's responsibility to close f when finished.
298 // Closing l does not affect f, and closing f does not affect l.
300 // The returned os.File's file descriptor is different from the
301 // connection's. Attempting to change properties of the original
302 // using this duplicate may or may not have the desired effect.
303 func (l
*UnixListener
) File() (f
*os
.File
, err error
) {
305 return nil, syscall
.EINVAL
309 err
= &OpError
{Op
: "file", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
314 // ListenUnix acts like Listen for Unix networks.
316 // The network must be "unix" or "unixpacket".
317 func ListenUnix(network
string, laddr
*UnixAddr
) (*UnixListener
, error
) {
319 case "unix", "unixpacket":
321 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: laddr
.opAddr(), Err
: UnknownNetworkError(network
)}
324 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: laddr
.opAddr(), Err
: errMissingAddress
}
326 sl
:= &sysListener
{network
: network
, address
: laddr
.String()}
327 ln
, err
:= sl
.listenUnix(context
.Background(), laddr
)
329 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: laddr
.opAddr(), Err
: err
}
334 // ListenUnixgram acts like ListenPacket for Unix networks.
336 // The network must be "unixgram".
337 func ListenUnixgram(network
string, laddr
*UnixAddr
) (*UnixConn
, error
) {
341 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: laddr
.opAddr(), Err
: UnknownNetworkError(network
)}
344 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: nil, Err
: errMissingAddress
}
346 sl
:= &sysListener
{network
: network
, address
: laddr
.String()}
347 c
, err
:= sl
.listenUnixgram(context
.Background(), laddr
)
349 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: laddr
.opAddr(), Err
: err
}