func (d *Dialer) Dial(network, address string) (Conn, error) {
addrs, err := resolveAddrList("dial", network, address, d.deadline())
if err != nil {
- return nil, &OpError{Op: "dial", Net: network, Addr: nil, Err: err}
+ return nil, &OpError{Op: "dial", Net: network, Source: nil, Addr: nil, Err: err}
}
var dialer func(deadline time.Time) (Conn, error)
if d.DualStack && network == "tcp" {
// the destination address.
func dialSingle(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err error) {
if la != nil && la.Network() != ra.Network() {
- return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: errors.New("mismatched local address type " + la.Network())}
+ return nil, &OpError{Op: "dial", Net: net, Source: la, Addr: ra, Err: errors.New("mismatched local address type " + la.Network())}
}
switch ra := ra.(type) {
case *TCPAddr:
la, _ := la.(*UnixAddr)
c, err = dialUnix(net, la, ra, deadline)
default:
- return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: addr}}
+ return nil, &OpError{Op: "dial", Net: net, Source: la, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: addr}}
}
if err != nil {
return nil, err // c is non-nil interface containing nil pointer
func Listen(net, laddr string) (Listener, error) {
addrs, err := resolveAddrList("listen", net, laddr, noDeadline)
if err != nil {
- return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: nil, Err: err}
}
var l Listener
switch la := addrs.first(isIPv4).(type) {
case *UnixAddr:
l, err = ListenUnix(net, la)
default:
- return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
}
if err != nil {
return nil, err // l is non-nil interface containing nil pointer
func ListenPacket(net, laddr string) (PacketConn, error) {
addrs, err := resolveAddrList("listen", net, laddr, noDeadline)
if err != nil {
- return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: nil, Err: err}
}
var l PacketConn
switch la := addrs.first(isIPv4).(type) {
case *UnixAddr:
l, err = ListenUnixgram(net, la)
default:
- return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
}
if err != nil {
return nil, err // l is non-nil interface containing nil pointer
}
timeout := deadline.Sub(time.Now())
if timeout <= 0 {
- return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: errTimeout}
+ return nil, &OpError{Op: "dial", Net: net, Source: nil, Addr: ra, Err: errTimeout}
}
t := time.NewTimer(timeout)
defer t.Stop()
}()
select {
case <-t.C:
- return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: errTimeout}
+ return nil, &OpError{Op: "dial", Net: net, Source: nil, Addr: ra, Err: errTimeout}
case racer := <-ch:
return racer.Conn, racer.error
}
if e.Net == "" {
return fmt.Errorf("OpError.Net is empty: %v", e)
}
- switch addr := e.Addr.(type) {
- case *TCPAddr:
- if addr == nil {
- return fmt.Errorf("OpError.Addr is empty: %v", e)
- }
- case *UDPAddr:
- if addr == nil {
- return fmt.Errorf("OpError.Addr is empty: %v", e)
- }
- case *IPAddr:
- if addr == nil {
- return fmt.Errorf("OpError.Addr is empty: %v", e)
- }
- case *IPNet:
- if addr == nil {
- return fmt.Errorf("OpError.Addr is empty: %v", e)
- }
- case *UnixAddr:
- if addr == nil {
- return fmt.Errorf("OpError.Addr is empty: %v", e)
- }
- case *pipeAddr:
- if addr == nil {
- return fmt.Errorf("OpError.Addr is empty: %v", e)
- }
- case fileAddr:
- if addr == "" {
- return fmt.Errorf("OpError.Addr is empty: %v", e)
+ for _, addr := range []Addr{e.Source, e.Addr} {
+ if addr != nil {
+ switch addr.(type) {
+ case *TCPAddr, *UDPAddr, *IPAddr, *IPNet, *UnixAddr, *pipeAddr, fileAddr:
+ default:
+ return fmt.Errorf("OpError.Source or Addr is unknown type: %T, %v", addr, e)
+ }
}
}
if e.Err == nil {
func FileConn(f *os.File) (c Conn, err error) {
c, err = fileConn(f)
if err != nil {
- err = &OpError{Op: "file", Net: "file+net", Addr: fileAddr(f.Name()), Err: err}
+ err = &OpError{Op: "file", Net: "file+net", Source: nil, Addr: fileAddr(f.Name()), Err: err}
}
return
}
func FileListener(f *os.File) (ln Listener, err error) {
ln, err = fileListener(f)
if err != nil {
- err = &OpError{Op: "file", Net: "file+net", Addr: fileAddr(f.Name()), Err: err}
+ err = &OpError{Op: "file", Net: "file+net", Source: nil, Addr: fileAddr(f.Name()), Err: err}
}
return
}
func FilePacketConn(f *os.File) (c PacketConn, err error) {
c, err = filePacketConn(f)
if err != nil {
- err = &OpError{Op: "file", Net: "file+net", Addr: fileAddr(f.Name()), Err: err}
+ err = &OpError{Op: "file", Net: "file+net", Source: nil, Addr: fileAddr(f.Name()), Err: err}
}
return
}
// Addrs returns interface addresses for a specific interface.
func (ifi *Interface) Addrs() ([]Addr, error) {
if ifi == nil {
- return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errInvalidInterface}
+ return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterface}
}
ifat, err := interfaceAddrTable(ifi)
if err != nil {
- err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
+ err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
}
return ifat, err
}
// a specific interface.
func (ifi *Interface) MulticastAddrs() ([]Addr, error) {
if ifi == nil {
- return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errInvalidInterface}
+ return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterface}
}
ifat, err := interfaceMulticastAddrTable(ifi)
if err != nil {
- err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
+ err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
}
return ifat, err
}
func Interfaces() ([]Interface, error) {
ift, err := interfaceTable(0)
if err != nil {
- err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
+ err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
}
return ift, err
}
func InterfaceAddrs() ([]Addr, error) {
ifat, err := interfaceAddrTable(nil)
if err != nil {
- err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
+ err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
}
return ifat, err
}
// InterfaceByIndex returns the interface specified by index.
func InterfaceByIndex(index int) (*Interface, error) {
if index <= 0 {
- return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errInvalidInterfaceIndex}
+ return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterfaceIndex}
}
ift, err := interfaceTable(index)
if err != nil {
- return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
+ return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
}
ifi, err := interfaceByIndex(ift, index)
if err != nil {
- err = &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
+ err = &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
}
return ifi, err
}
// InterfaceByName returns the interface specified by name.
func InterfaceByName(name string) (*Interface, error) {
if name == "" {
- return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errInvalidInterfaceName}
+ return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errInvalidInterfaceName}
}
ift, err := interfaceTable(0)
if err != nil {
- return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: err}
+ return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: err}
}
for _, ifi := range ift {
if name == ifi.Name {
return &ifi, nil
}
}
- return nil, &OpError{Op: "route", Net: "ip+net", Addr: nil, Err: errNoSuchInterface}
+ return nil, &OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errNoSuchInterface}
}
// Timeout() == true after a fixed time limit; see SetDeadline and
// SetReadDeadline.
func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) {
- return 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9}
+ return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
}
// ReadFrom implements the PacketConn ReadFrom method.
func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
- return 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9}
+ return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
}
// ReadMsgIP reads a packet from c, copying the payload into b and the
// bytes copied into b, the number of bytes copied into oob, the flags
// that were set on the packet and the source address of the packet.
func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error) {
- return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9}
+ return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
}
// WriteToIP writes an IP packet to addr via c, copying the payload
// SetWriteDeadline. On packet-oriented connections, write timeouts
// are rare.
func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EPLAN9}
+ return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
}
// WriteTo implements the PacketConn WriteTo method.
func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error) {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EPLAN9}
+ return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
}
// WriteMsgIP writes a packet to addr via c, copying the payload from
// b and the associated out-of-band data from oob. It returns the
// number of payload and out-of-band bytes written.
func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error) {
- return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EPLAN9}
+ return 0, 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
}
// DialIP connects to the remote address raddr on the network protocol
}
func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) {
- return nil, syscall.EPLAN9
+ return nil, &OpError{Op: "dial", Net: netProto, Source: laddr, Addr: raddr, Err: syscall.EPLAN9}
}
// ListenIP listens for incoming IP packets addressed to the local
// methods can be used to receive and send IP packets with per-packet
// addressing.
func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
- return nil, syscall.EPLAN9
+ return nil, &OpError{Op: "listen", Net: netProto, Source: nil, Addr: laddr, Err: syscall.EPLAN9}
}
addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
}
if err != nil {
- err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return n, addr, err
}
addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
}
if err != nil {
- err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return
}
return 0, syscall.EINVAL
}
if c.fd.isConnected {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+ return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: ErrWriteToConnected}
}
if addr == nil {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+ return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: errMissingAddress}
}
sa, err := addr.sockaddr(c.fd.family)
if err != nil {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err}
+ return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
}
n, err := c.fd.writeTo(b, sa)
if err != nil {
- err = &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err}
+ err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
}
return n, err
}
}
a, ok := addr.(*IPAddr)
if !ok {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EINVAL}
+ return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
}
return c.WriteToIP(b, a)
}
return 0, 0, syscall.EINVAL
}
if c.fd.isConnected {
- return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+ return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: ErrWriteToConnected}
}
if addr == nil {
- return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+ return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: errMissingAddress}
}
var sa syscall.Sockaddr
sa, err = addr.sockaddr(c.fd.family)
if err != nil {
- return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err}
+ return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
}
n, oobn, err = c.fd.writeMsg(b, oob, sa)
if err != nil {
- err = &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err}
+ err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
}
return
}
func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) {
net, proto, err := parseNetwork(netProto)
if err != nil {
- return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: err}
+ return nil, &OpError{Op: "dial", Net: netProto, Source: laddr, Addr: raddr, Err: err}
}
switch net {
case "ip", "ip4", "ip6":
default:
- return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: UnknownNetworkError(netProto)}
+ return nil, &OpError{Op: "dial", Net: netProto, Source: laddr, Addr: raddr, Err: UnknownNetworkError(netProto)}
}
if raddr == nil {
- return nil, &OpError{Op: "dial", Net: netProto, Addr: nil, Err: errMissingAddress}
+ return nil, &OpError{Op: "dial", Net: netProto, Source: laddr, Addr: raddr, Err: errMissingAddress}
}
fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_RAW, proto, "dial")
if err != nil {
- return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: err}
+ return nil, &OpError{Op: "dial", Net: netProto, Source: laddr, Addr: raddr, Err: err}
}
return newIPConn(fd), nil
}
func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
net, proto, err := parseNetwork(netProto)
if err != nil {
- return nil, &OpError{Op: "dial", Net: netProto, Addr: laddr, Err: err}
+ return nil, &OpError{Op: "dial", Net: netProto, Source: nil, Addr: laddr, Err: err}
}
switch net {
case "ip", "ip4", "ip6":
default:
- return nil, &OpError{Op: "listen", Net: netProto, Addr: laddr, Err: UnknownNetworkError(netProto)}
+ return nil, &OpError{Op: "listen", Net: netProto, Source: nil, Addr: laddr, Err: UnknownNetworkError(netProto)}
}
fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_RAW, proto, "listen")
if err != nil {
- return nil, &OpError{Op: "listen", Net: netProto, Addr: laddr, Err: err}
+ return nil, &OpError{Op: "listen", Net: netProto, Source: nil, Addr: laddr, Err: err}
}
return newIPConn(fd), nil
}
defer func() { netErr(err) }()
f, dest, proto, name, err := startPlan9(net, raddr)
if err != nil {
- return nil, &OpError{"dial", net, raddr, err}
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: err}
}
_, err = f.WriteString("connect " + dest)
if err != nil {
f.Close()
- return nil, &OpError{"dial", f.Name(), raddr, err}
+ return nil, &OpError{Op: "dial", Net: f.Name(), Source: laddr, Addr: raddr, Err: err}
}
data, err := os.OpenFile(netdir+"/"+proto+"/"+name+"/data", os.O_RDWR, 0)
if err != nil {
f.Close()
- return nil, &OpError{"dial", net, raddr, err}
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: err}
}
laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local")
if err != nil {
data.Close()
f.Close()
- return nil, &OpError{"dial", proto, raddr, err}
+ return nil, &OpError{Op: "dial", Net: proto, Source: laddr, Addr: raddr, Err: err}
}
return newFD(proto, name, f, data, laddr, raddr)
}
defer func() { netErr(err) }()
f, dest, proto, name, err := startPlan9(net, laddr)
if err != nil {
- return nil, &OpError{"listen", net, laddr, err}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
}
_, err = f.WriteString("announce " + dest)
if err != nil {
f.Close()
- return nil, &OpError{"announce", proto, laddr, err}
+ return nil, &OpError{Op: "announce", Net: proto, Source: nil, Addr: laddr, Err: err}
}
laddr, err = readPlan9Addr(proto, netdir+"/"+proto+"/"+name+"/local")
if err != nil {
f.Close()
- return nil, &OpError{Op: "listen", Net: net, Err: err}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
}
return newFD(proto, name, f, nil, laddr, nil)
}
-func (l *netFD) netFD() (*netFD, error) {
- return newFD(l.net, l.n, l.ctl, l.data, l.laddr, l.raddr)
+func (fd *netFD) netFD() (*netFD, error) {
+ return newFD(fd.net, fd.n, fd.ctl, fd.data, fd.laddr, fd.raddr)
}
-func (l *netFD) acceptPlan9() (fd *netFD, err error) {
+func (fd *netFD) acceptPlan9() (nfd *netFD, err error) {
defer func() { netErr(err) }()
- if err := l.readLock(); err != nil {
+ if err := fd.readLock(); err != nil {
return nil, err
}
- defer l.readUnlock()
- f, err := os.Open(l.dir + "/listen")
+ defer fd.readUnlock()
+ f, err := os.Open(fd.dir + "/listen")
if err != nil {
- return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err}
+ return nil, &OpError{Op: "accept", Net: fd.dir + "/listen", Source: nil, Addr: fd.laddr, Err: err}
}
var buf [16]byte
n, err := f.Read(buf[:])
if err != nil {
f.Close()
- return nil, &OpError{"accept", l.dir + "/listen", l.laddr, err}
+ return nil, &OpError{Op: "accept", Net: fd.dir + "/listen", Source: nil, Addr: fd.laddr, Err: err}
}
name := string(buf[:n])
- data, err := os.OpenFile(netdir+"/"+l.net+"/"+name+"/data", os.O_RDWR, 0)
+ data, err := os.OpenFile(netdir+"/"+fd.net+"/"+name+"/data", os.O_RDWR, 0)
if err != nil {
f.Close()
- return nil, &OpError{"accept", l.net, l.laddr, err}
+ return nil, &OpError{Op: "accept", Net: fd.net, Source: nil, Addr: fd.laddr, Err: err}
}
- raddr, err := readPlan9Addr(l.net, netdir+"/"+l.net+"/"+name+"/remote")
+ raddr, err := readPlan9Addr(fd.net, netdir+"/"+fd.net+"/"+name+"/remote")
if err != nil {
data.Close()
f.Close()
- return nil, &OpError{"accept", l.net, l.laddr, err}
+ return nil, &OpError{Op: "accept", Net: fd.net, Source: nil, Addr: fd.laddr, Err: err}
}
- return newFD(l.net, name, f, data, l.laddr, raddr)
+ return newFD(fd.net, name, f, data, fd.laddr, raddr)
}
}
n, err := c.fd.Read(b)
if err != nil && err != io.EOF {
- err = &OpError{Op: "read", Net: c.fd.net, Err: err}
- if c.fd.raddr != nil {
- err.(*OpError).Addr = c.fd.raddr
- } else {
- err.(*OpError).Addr = c.fd.laddr // for unconnected-mode sockets
- }
+ err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return n, err
}
}
n, err := c.fd.Write(b)
if err != nil {
- err = &OpError{Op: "write", Net: c.fd.net, Err: err}
- if c.fd.raddr != nil {
- err.(*OpError).Addr = c.fd.raddr
- } else {
- err.(*OpError).Addr = c.fd.laddr // for unconnected-mode sockets
- }
+ err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return n, err
}
}
err := c.fd.Close()
if err != nil {
- err = &OpError{Op: "close", Net: c.fd.net, Err: err}
- if c.fd.raddr != nil {
- err.(*OpError).Addr = c.fd.raddr
- } else {
- err.(*OpError).Addr = c.fd.laddr // for unconnected-mode sockets
- }
+ err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return err
}
return syscall.EINVAL
}
if err := c.fd.setDeadline(t); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
}
return nil
}
return syscall.EINVAL
}
if err := c.fd.setReadDeadline(t); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
}
return nil
}
return syscall.EINVAL
}
if err := c.fd.setWriteDeadline(t); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
}
return nil
}
return syscall.EINVAL
}
if err := setReadBuffer(c.fd, bytes); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
}
return nil
}
return syscall.EINVAL
}
if err := setWriteBuffer(c.fd, bytes); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
}
return nil
}
func (c *conn) File() (f *os.File, err error) {
f, err = c.fd.dup()
if err != nil {
- err = &OpError{Op: "file", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return
}
// such as "tcp" or "udp6".
Net string
- // Addr is the network address on which this error occurred.
+ // For operations involving a remote network connection, like
+ // Dial, Read, or Write, Source is the corresponding local
+ // network address.
+ Source Addr
+
+ // Addr is the network address for which this error occurred.
+ // For local operations, like Listen or SetDeadline, Addr is
+ // the address of the local endpoint being manipulated.
+ // For operations involving a remote network connection, like
+ // Dial, Read, or Write, Addr is the remote address of that
+ // connection.
Addr Addr
// Err is the error that occurred during the operation.
if e.Net != "" {
s += " " + e.Net
}
+ if e.Source != nil {
+ s += " " + e.Source.String()
+ }
if e.Addr != nil {
- s += " " + e.Addr.String()
+ if e.Source != nil {
+ s += "->"
+ } else {
+ s += " "
+ }
+ s += e.Addr.String()
}
s += ": " + e.Err.Error()
return s
}
func (p *pipe) SetDeadline(t time.Time) error {
- return errors.New("net.Pipe does not support deadlines")
+ return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}
func (p *pipe) SetReadDeadline(t time.Time) error {
- return errors.New("net.Pipe does not support deadlines")
+ return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}
func (p *pipe) SetWriteDeadline(t time.Time) error {
- return errors.New("net.Pipe does not support deadlines")
+ return &OpError{Op: "set", Net: "pipe", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}
func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
n, err := genericReadFrom(c, r)
if err != nil && err != io.EOF {
- err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.raddr, Err: err}
+ err = &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return n, err
}
}
err := c.fd.closeRead()
if err != nil {
- err = &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: err}
+ err = &OpError{Op: "close", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return err
}
}
err := c.fd.closeWrite()
if err != nil {
- err = &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: err}
+ err = &OpError{Op: "close", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return err
}
// some operating systems after sec seconds have elapsed any remaining
// unsent data may be discarded.
func (c *TCPConn) SetLinger(sec int) error {
- return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9}
+ return &OpError{Op: "set", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
}
// SetKeepAlive sets whether the operating system should send
return syscall.EPLAN9
}
if err := setKeepAlive(c.fd, keepalive); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return nil
}
return syscall.EPLAN9
}
if err := setKeepAlivePeriod(c.fd, d); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return nil
}
// algorithm). The default is true (no delay), meaning that data is
// sent as soon as possible after a Write.
func (c *TCPConn) SetNoDelay(noDelay bool) error {
- return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9}
+ return &OpError{Op: "set", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
}
// DialTCP connects to the remote address raddr on the network net,
switch net {
case "tcp", "tcp4", "tcp6":
default:
- return nil, &OpError{"dial", net, raddr, UnknownNetworkError(net)}
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: UnknownNetworkError(net)}
}
if raddr == nil {
- return nil, &OpError{"dial", net, nil, errMissingAddress}
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: errMissingAddress}
}
fd, err := dialPlan9(net, laddr, raddr)
if err != nil {
}
if _, err := l.fd.ctl.WriteString("hangup"); err != nil {
l.fd.ctl.Close()
- return &OpError{Op: "close", Net: l.fd.net, Addr: l.fd.laddr, Err: err}
+ return &OpError{Op: "close", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: err}
}
err := l.fd.ctl.Close()
if err != nil {
- err = &OpError{Op: "close", Net: l.fd.net, Addr: l.fd.laddr, Err: err}
+ err = &OpError{Op: "close", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: err}
}
return err
}
return syscall.EINVAL
}
if err := l.fd.setDeadline(t); err != nil {
- return &OpError{Op: "set", Net: l.fd.net, Addr: l.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: err}
}
return nil
}
func (l *TCPListener) File() (f *os.File, err error) {
f, err = l.dup()
if err != nil {
- err = &OpError{Op: "file", Net: l.fd.net, Addr: l.fd.laddr, Err: err}
+ err = &OpError{Op: "file", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: err}
}
return
}
switch net {
case "tcp", "tcp4", "tcp6":
default:
- return nil, &OpError{"listen", net, laddr, UnknownNetworkError(net)}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: UnknownNetworkError(net)}
}
if laddr == nil {
laddr = &TCPAddr{}
func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
if n, err, handled := sendFile(c.fd, r); handled {
if err != nil && err != io.EOF {
- err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.raddr, Err: err}
+ err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return n, err
}
n, err := genericReadFrom(c, r)
if err != nil && err != io.EOF {
- err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.raddr, Err: err}
+ err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return n, err
}
}
err := c.fd.closeRead()
if err != nil {
- err = &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: err}
+ err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return err
}
}
err := c.fd.closeWrite()
if err != nil {
- err = &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: err}
+ err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return err
}
return syscall.EINVAL
}
if err := setLinger(c.fd, sec); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return nil
}
return syscall.EINVAL
}
if err := setKeepAlive(c.fd, keepalive); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return nil
}
return syscall.EINVAL
}
if err := setKeepAlivePeriod(c.fd, d); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return nil
}
return syscall.EINVAL
}
if err := setNoDelay(c.fd, noDelay); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return nil
}
switch net {
case "tcp", "tcp4", "tcp6":
default:
- return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)}
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: UnknownNetworkError(net)}
}
if raddr == nil {
- return nil, &OpError{Op: "dial", Net: net, Addr: nil, Err: errMissingAddress}
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: errMissingAddress}
}
return dialTCP(net, laddr, raddr, noDeadline)
}
}
if err != nil {
- return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err}
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: err}
}
return newTCPConn(fd), nil
}
}
fd, err := l.fd.accept()
if err != nil {
- return nil, &OpError{Op: "accept", Net: l.fd.net, Addr: l.fd.laddr, Err: err}
+ return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
}
return newTCPConn(fd), nil
}
}
err := l.fd.Close()
if err != nil {
- err = &OpError{Op: "close", Net: l.fd.net, Addr: l.fd.laddr, Err: err}
+ err = &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
}
return err
}
return syscall.EINVAL
}
if err := l.fd.setDeadline(t); err != nil {
- return &OpError{Op: "set", Net: l.fd.net, Addr: l.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
}
return nil
}
func (l *TCPListener) File() (f *os.File, err error) {
f, err = l.fd.dup()
if err != nil {
- err = &OpError{Op: "file", Net: l.fd.net, Addr: l.fd.laddr, Err: err}
+ err = &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
}
return
}
switch net {
case "tcp", "tcp4", "tcp6":
default:
- return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: UnknownNetworkError(net)}
}
if laddr == nil {
laddr = &TCPAddr{}
}
fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_STREAM, 0, "listen")
if err != nil {
- return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
}
return &TCPListener{fd}, nil
}
buf := make([]byte, udpHeaderSize+len(b))
m, err := c.fd.data.Read(buf)
if err != nil {
- return 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
if m < udpHeaderSize {
- return 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: errors.New("short read reading UDP header")}
+ return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: errors.New("short read reading UDP header")}
}
buf = buf[:m]
// flags that were set on the packet and the source address of the
// packet.
func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
- return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9}
+ return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
}
// WriteToUDP writes a UDP packet to addr via c, copying the payload
return 0, syscall.EINVAL
}
if addr == nil {
- return 0, &OpError{Op: "write", Net: c.fd.dir, Addr: nil, Err: errMissingAddress}
+ return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: errMissingAddress}
}
h := new(udpHeader)
h.raddr = addr.IP.To16()
i := copy(buf, h.Bytes())
copy(buf[i:], b)
if _, err := c.fd.data.Write(buf); err != nil {
- return 0, &OpError{Op: "write", Net: c.fd.dir, Addr: addr, Err: err}
+ return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: err}
}
return len(b), nil
}
}
a, ok := addr.(*UDPAddr)
if !ok {
- return 0, &OpError{Op: "write", Net: c.fd.dir, Addr: addr, Err: syscall.EINVAL}
+ return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
}
return c.WriteToUDP(b, a)
}
// out-of-band data is copied from oob. It returns the number of
// payload and out-of-band bytes written.
func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
- return 0, 0, &OpError{Op: "write", Net: c.fd.dir, Addr: addr, Err: syscall.EPLAN9}
+ return 0, 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
}
// DialUDP connects to the remote address raddr on the network net,
switch net {
case "udp", "udp4", "udp6":
default:
- return nil, UnknownNetworkError(net)
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: UnknownNetworkError(net)}
}
if raddr == nil {
- return nil, &OpError{"dial", net, nil, errMissingAddress}
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: errMissingAddress}
}
fd, err := dialPlan9(net, laddr, raddr)
if err != nil {
switch net {
case "udp", "udp4", "udp6":
default:
- return nil, UnknownNetworkError(net)
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: UnknownNetworkError(net)}
}
if laddr == nil {
laddr = &UDPAddr{}
}
_, err = l.ctl.WriteString("headers")
if err != nil {
- return nil, err
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
}
l.data, err = os.OpenFile(l.dir+"/data", os.O_RDWR, 0)
if err != nil {
- return nil, err
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
}
fd, err := l.netFD()
return newUDPConn(fd), err
// interface to join. ListenMulticastUDP uses default multicast
// interface if ifi is nil.
func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
- return nil, syscall.EPLAN9
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: gaddr, Err: syscall.EPLAN9}
}
addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
}
if err != nil {
- err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return n, addr, err
}
addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
}
if err != nil {
- err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return
}
return 0, syscall.EINVAL
}
if c.fd.isConnected {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+ return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: ErrWriteToConnected}
}
if addr == nil {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+ return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: errMissingAddress}
}
sa, err := addr.sockaddr(c.fd.family)
if err != nil {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err}
+ return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
}
n, err := c.fd.writeTo(b, sa)
if err != nil {
- err = &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err}
+ err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
}
return n, err
}
}
a, ok := addr.(*UDPAddr)
if !ok {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EINVAL}
+ return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
}
return c.WriteToUDP(b, a)
}
return 0, 0, syscall.EINVAL
}
if c.fd.isConnected && addr != nil {
- return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+ return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: ErrWriteToConnected}
}
if !c.fd.isConnected && addr == nil {
- return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+ return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: errMissingAddress}
}
var sa syscall.Sockaddr
sa, err = addr.sockaddr(c.fd.family)
if err != nil {
- return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err}
+ return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
}
n, oobn, err = c.fd.writeMsg(b, oob, sa)
if err != nil {
- err = &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err}
+ err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
}
return
}
switch net {
case "udp", "udp4", "udp6":
default:
- return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)}
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: UnknownNetworkError(net)}
}
if raddr == nil {
- return nil, &OpError{Op: "dial", Net: net, Addr: nil, Err: errMissingAddress}
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: errMissingAddress}
}
return dialUDP(net, laddr, raddr, noDeadline)
}
func dialUDP(net string, laddr, raddr *UDPAddr, deadline time.Time) (*UDPConn, error) {
fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_DGRAM, 0, "dial")
if err != nil {
- return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err}
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: err}
}
return newUDPConn(fd), nil
}
switch net {
case "udp", "udp4", "udp6":
default:
- return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: UnknownNetworkError(net)}
}
if laddr == nil {
laddr = &UDPAddr{}
}
fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen")
if err != nil {
- return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
}
return newUDPConn(fd), nil
}
switch net {
case "udp", "udp4", "udp6":
default:
- return nil, &OpError{Op: "listen", Net: net, Addr: gaddr, Err: UnknownNetworkError(net)}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: gaddr, Err: UnknownNetworkError(net)}
}
if gaddr == nil || gaddr.IP == nil {
- return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: gaddr, Err: errMissingAddress}
}
fd, err := internetSocket(net, gaddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen")
if err != nil {
- return nil, &OpError{Op: "listen", Net: net, Addr: gaddr, Err: err}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: gaddr, Err: err}
}
c := newUDPConn(fd)
if ip4 := gaddr.IP.To4(); ip4 != nil {
if err := listenIPv4MulticastUDP(c, ifi, ip4); err != nil {
c.Close()
- return nil, &OpError{Op: "listen", Net: net, Addr: &IPAddr{IP: ip4}, Err: err}
+ return nil, &OpError{Op: "listen", Net: net, Source: c.fd.laddr, Addr: &IPAddr{IP: ip4}, Err: err}
}
} else {
if err := listenIPv6MulticastUDP(c, ifi, gaddr.IP); err != nil {
c.Close()
- return nil, &OpError{Op: "listen", Net: net, Addr: &IPAddr{IP: gaddr.IP}, Err: err}
+ return nil, &OpError{Op: "listen", Net: net, Source: c.fd.laddr, Addr: &IPAddr{IP: gaddr.IP}, Err: err}
}
}
return c, nil
// Timeout() == true after a fixed time limit; see SetDeadline and
// SetReadDeadline.
func (c *UnixConn) ReadFromUnix(b []byte) (int, *UnixAddr, error) {
- return 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9}
+ return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
}
// ReadFrom implements the PacketConn ReadFrom method.
func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error) {
- return 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9}
+ return 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
}
// ReadMsgUnix reads a packet from c, copying the payload into b and
// bytes copied into b, the number of bytes copied into oob, the flags
// that were set on the packet, and the source address of the packet.
func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) {
- return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: syscall.EPLAN9}
+ return 0, 0, 0, nil, &OpError{Op: "read", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
}
// WriteToUnix writes a packet to addr via c, copying the payload from b.
// SetWriteDeadline. On packet-oriented connections, write timeouts
// are rare.
func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (int, error) {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EPLAN9}
+ return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
}
// WriteTo implements the PacketConn WriteTo method.
func (c *UnixConn) WriteTo(b []byte, addr Addr) (int, error) {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EPLAN9}
+ return 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
}
// WriteMsgUnix writes a packet to addr via c, copying the payload
// from b and the associated out-of-band data from oob. It returns
// the number of payload and out-of-band bytes written.
func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) {
- return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EPLAN9}
+ return 0, 0, &OpError{Op: "write", Net: c.fd.dir, Source: c.fd.laddr, Addr: addr, Err: syscall.EPLAN9}
}
// CloseRead shuts down the reading side of the Unix domain connection.
// Most callers should just use Close.
func (c *UnixConn) CloseRead() error {
- return &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: syscall.EPLAN9}
+ return &OpError{Op: "close", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
}
// CloseWrite shuts down the writing side of the Unix domain connection.
// Most callers should just use Close.
func (c *UnixConn) CloseWrite() error {
- return &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: syscall.EPLAN9}
+ return &OpError{Op: "close", Net: c.fd.dir, Source: c.fd.laddr, Addr: c.fd.raddr, Err: syscall.EPLAN9}
}
// DialUnix connects to the remote address raddr on the network net,
}
func dialUnix(net string, laddr, raddr *UnixAddr, deadline time.Time) (*UnixConn, error) {
- return nil, syscall.EPLAN9
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: syscall.EPLAN9}
}
// UnixListener is a Unix domain socket listener. Clients should
// typically use variables of type Listener instead of assuming Unix
// domain sockets.
-type UnixListener struct{}
+type UnixListener struct {
+ fd *netFD
+}
// ListenUnix announces on the Unix domain socket laddr and returns a
// Unix listener. The network net must be "unix" or "unixpacket".
func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) {
- return nil, syscall.EPLAN9
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: syscall.EPLAN9}
}
// AcceptUnix accepts the next incoming call and returns the new
// connection.
func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
- return nil, &OpError{Op: "accept", Net: "<nil>", Addr: nil, Err: syscall.EPLAN9}
+ return nil, &OpError{Op: "accept", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
}
// Accept implements the Accept method in the Listener interface; it
// waits for the next call and returns a generic Conn.
func (l *UnixListener) Accept() (Conn, error) {
- return nil, &OpError{Op: "accept", Net: "<nil>", Addr: nil, Err: syscall.EPLAN9}
+ return nil, &OpError{Op: "accept", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
}
// Close stops listening on the Unix address. Already accepted
// connections are not closed.
func (l *UnixListener) Close() error {
- return &OpError{Op: "close", Net: "<nil>", Addr: nil, Err: syscall.EPLAN9}
+ return &OpError{Op: "close", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
}
// Addr returns the listener's network address.
// SetDeadline sets the deadline associated with the listener.
// A zero time value disables the deadline.
func (l *UnixListener) SetDeadline(t time.Time) error {
- return &OpError{Op: "set", Net: "<nil>", Addr: nil, Err: syscall.EPLAN9}
+ return &OpError{Op: "set", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
}
// File returns a copy of the underlying os.File, set to blocking
// connection's. Attempting to change properties of the original
// using this duplicate may or may not have the desired effect.
func (l *UnixListener) File() (*os.File, error) {
- return nil, &OpError{Op: "file", Net: "<nil>", Addr: nil, Err: syscall.EPLAN9}
+ return nil, &OpError{Op: "file", Net: l.fd.dir, Source: nil, Addr: l.fd.laddr, Err: syscall.EPLAN9}
}
// ListenUnixgram listens for incoming Unix datagram packets addressed
// The returned connection's ReadFrom and WriteTo methods can be used
// to receive and send packets with per-packet addressing.
func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error) {
- return nil, syscall.EPLAN9
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: syscall.EPLAN9}
}
}
}
if err != nil {
- err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return n, addr, err
}
}
}
if err != nil {
- err = &OpError{Op: "read", Net: c.fd.net, Addr: c.fd.laddr, Err: err}
+ err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return
}
return 0, syscall.EINVAL
}
if c.fd.isConnected {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+ return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: ErrWriteToConnected}
}
if addr == nil {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+ return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: errMissingAddress}
}
if addr.Net != sotypeToNet(c.fd.sotype) {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EAFNOSUPPORT}
+ return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EAFNOSUPPORT}
}
sa := &syscall.SockaddrUnix{Name: addr.Name}
n, err := c.fd.writeTo(b, sa)
if err != nil {
- err = &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err}
+ err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
}
return n, err
}
}
a, ok := addr.(*UnixAddr)
if !ok {
- return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EINVAL}
+ return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
}
return c.WriteToUnix(b, a)
}
return 0, 0, syscall.EINVAL
}
if c.fd.sotype == syscall.SOCK_DGRAM && c.fd.isConnected {
- return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+ return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: ErrWriteToConnected}
}
var sa syscall.Sockaddr
if addr != nil {
if addr.Net != sotypeToNet(c.fd.sotype) {
- return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: syscall.EAFNOSUPPORT}
+ return 0, 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EAFNOSUPPORT}
}
sa = &syscall.SockaddrUnix{Name: addr.Name}
}
n, oobn, err = c.fd.writeMsg(b, oob, sa)
if err != nil {
- err = &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: err}
+ err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: err}
}
return
}
}
err := c.fd.closeRead()
if err != nil {
- err = &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: err}
+ err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return err
}
}
err := c.fd.closeWrite()
if err != nil {
- err = &OpError{Op: "close", Net: c.fd.net, Addr: c.fd.raddr, Err: err}
+ err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return err
}
switch net {
case "unix", "unixgram", "unixpacket":
default:
- return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)}
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: UnknownNetworkError(net)}
}
return dialUnix(net, laddr, raddr, noDeadline)
}
func dialUnix(net string, laddr, raddr *UnixAddr, deadline time.Time) (*UnixConn, error) {
fd, err := unixSocket(net, laddr, raddr, "dial", deadline)
if err != nil {
- return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err}
+ return nil, &OpError{Op: "dial", Net: net, Source: laddr, Addr: raddr, Err: err}
}
return newUnixConn(fd), nil
}
switch net {
case "unix", "unixpacket":
default:
- return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: UnknownNetworkError(net)}
}
if laddr == nil {
- return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: errMissingAddress}
}
fd, err := unixSocket(net, laddr, nil, "listen", noDeadline)
if err != nil {
- return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
}
- return &UnixListener{fd, fd.laddr.String()}, nil
+ return &UnixListener{fd: fd, path: fd.laddr.String()}, nil
}
// AcceptUnix accepts the next incoming call and returns the new
}
fd, err := l.fd.accept()
if err != nil {
- return nil, &OpError{Op: "accept", Net: l.fd.net, Addr: l.fd.laddr, Err: err}
+ return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
}
return newUnixConn(fd), nil
}
}
err := l.fd.Close()
if err != nil {
- err = &OpError{Op: "close", Net: l.fd.net, Addr: l.fd.laddr, Err: err}
+ err = &OpError{Op: "close", Net: l.fd.net, Source: l.fd.laddr, Addr: l.fd.raddr, Err: err}
}
return err
}
return syscall.EINVAL
}
if err := l.fd.setDeadline(t); err != nil {
- return &OpError{Op: "set", Net: l.fd.net, Addr: l.fd.laddr, Err: err}
+ return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
}
return nil
}
func (l *UnixListener) File() (f *os.File, err error) {
f, err = l.fd.dup()
if err != nil {
- err = &OpError{Op: "file", Net: l.fd.net, Addr: l.fd.laddr, Err: err}
+ err = &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
}
return
}
switch net {
case "unixgram":
default:
- return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: UnknownNetworkError(net)}
}
if laddr == nil {
- return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: errMissingAddress}
}
fd, err := unixSocket(net, laddr, nil, "listen", noDeadline)
if err != nil {
- return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
+ return nil, &OpError{Op: "listen", Net: net, Source: nil, Addr: laddr, Err: err}
}
return newUnixConn(fd), nil
}