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, NaCl, Plan 9 and Windows, methods and functions
16 // related to UnixConn and UnixListener are not implemented.
18 // UnixAddr represents the address of a Unix domain socket end point.
19 type UnixAddr
struct {
24 // Network returns the address's network name, "unix", "unixgram" or
26 func (a
*UnixAddr
) Network() string {
30 func (a
*UnixAddr
) String() string {
37 func (a
*UnixAddr
) isWildcard() bool {
38 return a
== nil || a
.Name
== ""
41 func (a
*UnixAddr
) opAddr() Addr
{
48 // ResolveUnixAddr returns an address of Unix domain socket end point.
50 // The network must be a Unix network name.
52 // See func Dial for a description of the network and address
54 func ResolveUnixAddr(network
, address
string) (*UnixAddr
, error
) {
56 case "unix", "unixgram", "unixpacket":
57 return &UnixAddr
{Name
: address
, Net
: network
}, nil
59 return nil, UnknownNetworkError(network
)
63 // UnixConn is an implementation of the Conn interface for connections
64 // to Unix domain sockets.
65 type UnixConn
struct {
69 // SyscallConn returns a raw network connection.
70 // This implements the syscall.Conn interface.
71 func (c
*UnixConn
) SyscallConn() (syscall
.RawConn
, error
) {
73 return nil, syscall
.EINVAL
75 return newRawConn(c
.fd
)
78 // CloseRead shuts down the reading side of the Unix domain connection.
79 // Most callers should just use Close.
80 func (c
*UnixConn
) CloseRead() error
{
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
}
90 // CloseWrite shuts down the writing side of the Unix domain connection.
91 // Most callers should just use Close.
92 func (c
*UnixConn
) CloseWrite() error
{
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
}
102 // ReadFromUnix acts like ReadFrom but returns a UnixAddr.
103 func (c
*UnixConn
) ReadFromUnix(b
[]byte) (int, *UnixAddr
, error
) {
105 return 0, nil, syscall
.EINVAL
107 n
, addr
, err
:= c
.readFrom(b
)
109 err
= &OpError
{Op
: "read", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
114 // ReadFrom implements the PacketConn ReadFrom method.
115 func (c
*UnixConn
) ReadFrom(b
[]byte) (int, Addr
, error
) {
117 return 0, nil, syscall
.EINVAL
119 n
, addr
, err
:= c
.readFrom(b
)
121 err
= &OpError
{Op
: "read", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
129 // ReadMsgUnix reads a message from c, copying the payload into b and
130 // the associated out-of-band data into oob. It returns the number of
131 // bytes copied into b, the number of bytes copied into oob, the flags
132 // that were set on the message and the source address of the message.
134 // Note that if len(b) == 0 and len(oob) > 0, this function will still
135 // read (and discard) 1 byte from the connection.
136 func (c
*UnixConn
) ReadMsgUnix(b
, oob
[]byte) (n
, oobn
, flags
int, addr
*UnixAddr
, err error
) {
138 return 0, 0, 0, nil, syscall
.EINVAL
140 n
, oobn
, flags
, addr
, err
= c
.readMsg(b
, oob
)
142 err
= &OpError
{Op
: "read", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
147 // WriteToUnix acts like WriteTo but takes a UnixAddr.
148 func (c
*UnixConn
) WriteToUnix(b
[]byte, addr
*UnixAddr
) (int, error
) {
150 return 0, syscall
.EINVAL
152 n
, err
:= c
.writeTo(b
, addr
)
154 err
= &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: addr
.opAddr(), Err
: err
}
159 // WriteTo implements the PacketConn WriteTo method.
160 func (c
*UnixConn
) WriteTo(b
[]byte, addr Addr
) (int, error
) {
162 return 0, syscall
.EINVAL
164 a
, ok
:= addr
.(*UnixAddr
)
166 return 0, &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: addr
, Err
: syscall
.EINVAL
}
168 n
, err
:= c
.writeTo(b
, a
)
170 err
= &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: a
.opAddr(), Err
: err
}
175 // WriteMsgUnix writes a message to addr via c, copying the payload
176 // from b and the associated out-of-band data from oob. It returns the
177 // number of payload and out-of-band bytes written.
179 // Note that if len(b) == 0 and len(oob) > 0, this function will still
180 // write 1 byte to the connection.
181 func (c
*UnixConn
) WriteMsgUnix(b
, oob
[]byte, addr
*UnixAddr
) (n
, oobn
int, err error
) {
183 return 0, 0, syscall
.EINVAL
185 n
, oobn
, err
= c
.writeMsg(b
, oob
, addr
)
187 err
= &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: addr
.opAddr(), Err
: err
}
192 func newUnixConn(fd
*netFD
) *UnixConn
{ return &UnixConn
{conn
{fd
}} }
194 // DialUnix acts like Dial for Unix networks.
196 // The network must be a Unix network name; see func Dial for details.
198 // If laddr is non-nil, it is used as the local address for the
200 func DialUnix(network
string, laddr
, raddr
*UnixAddr
) (*UnixConn
, error
) {
202 case "unix", "unixgram", "unixpacket":
204 return nil, &OpError
{Op
: "dial", Net
: network
, Source
: laddr
.opAddr(), Addr
: raddr
.opAddr(), Err
: UnknownNetworkError(network
)}
206 sd
:= &sysDialer
{network
: network
, address
: raddr
.String()}
207 c
, err
:= sd
.dialUnix(context
.Background(), laddr
, raddr
)
209 return nil, &OpError
{Op
: "dial", Net
: network
, Source
: laddr
.opAddr(), Addr
: raddr
.opAddr(), Err
: err
}
214 // UnixListener is a Unix domain socket listener. Clients should
215 // typically use variables of type Listener instead of assuming Unix
217 type UnixListener
struct {
224 func (ln
*UnixListener
) ok() bool { return ln
!= nil && ln
.fd
!= nil }
226 // SyscallConn returns a raw network connection.
227 // This implements the syscall.Conn interface.
229 // The returned RawConn only supports calling Control. Read and
230 // Write return an error.
231 func (l
*UnixListener
) SyscallConn() (syscall
.RawConn
, error
) {
233 return nil, syscall
.EINVAL
235 return newRawListener(l
.fd
)
238 // AcceptUnix accepts the next incoming call and returns the new
240 func (l
*UnixListener
) AcceptUnix() (*UnixConn
, error
) {
242 return nil, syscall
.EINVAL
246 return nil, &OpError
{Op
: "accept", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
251 // Accept implements the Accept method in the Listener interface.
252 // Returned connections will be of type *UnixConn.
253 func (l
*UnixListener
) Accept() (Conn
, error
) {
255 return nil, syscall
.EINVAL
259 return nil, &OpError
{Op
: "accept", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
264 // Close stops listening on the Unix address. Already accepted
265 // connections are not closed.
266 func (l
*UnixListener
) Close() error
{
268 return syscall
.EINVAL
270 if err
:= l
.close(); err
!= nil {
271 return &OpError
{Op
: "close", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
276 // Addr returns the listener's network address.
277 // The Addr returned is shared by all invocations of Addr, so
279 func (l
*UnixListener
) Addr() Addr
{ return l
.fd
.laddr
}
281 // SetDeadline sets the deadline associated with the listener.
282 // A zero time value disables the deadline.
283 func (l
*UnixListener
) SetDeadline(t time
.Time
) error
{
285 return syscall
.EINVAL
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
}
293 // File returns a copy of the underlying os.File.
294 // It is the caller's responsibility to close f when finished.
295 // Closing l does not affect f, and closing f does not affect l.
297 // The returned os.File's file descriptor is different from the
298 // connection's. Attempting to change properties of the original
299 // using this duplicate may or may not have the desired effect.
300 func (l
*UnixListener
) File() (f
*os
.File
, err error
) {
302 return nil, syscall
.EINVAL
306 err
= &OpError
{Op
: "file", Net
: l
.fd
.net
, Source
: nil, Addr
: l
.fd
.laddr
, Err
: err
}
311 // ListenUnix acts like Listen for Unix networks.
313 // The network must be "unix" or "unixpacket".
314 func ListenUnix(network
string, laddr
*UnixAddr
) (*UnixListener
, error
) {
316 case "unix", "unixpacket":
318 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: laddr
.opAddr(), Err
: UnknownNetworkError(network
)}
321 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: laddr
.opAddr(), Err
: errMissingAddress
}
323 sl
:= &sysListener
{network
: network
, address
: laddr
.String()}
324 ln
, err
:= sl
.listenUnix(context
.Background(), laddr
)
326 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: laddr
.opAddr(), Err
: err
}
331 // ListenUnixgram acts like ListenPacket for Unix networks.
333 // The network must be "unixgram".
334 func ListenUnixgram(network
string, laddr
*UnixAddr
) (*UnixConn
, error
) {
338 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: laddr
.opAddr(), Err
: UnknownNetworkError(network
)}
341 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: nil, Err
: errMissingAddress
}
343 sl
:= &sysListener
{network
: network
, address
: laddr
.String()}
344 c
, err
:= sl
.listenUnixgram(context
.Background(), laddr
)
346 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: laddr
.opAddr(), Err
: err
}