]> Cypherpunks repositories - gostls13.git/commitdiff
net: fix inconsistent errors
authorMikio Hara <mikioh.mikioh@gmail.com>
Tue, 21 Apr 2015 12:20:15 +0000 (21:20 +0900)
committerMikio Hara <mikioh.mikioh@gmail.com>
Tue, 5 May 2015 09:40:07 +0000 (09:40 +0000)
These a series of changes fix inconsistent errors on the package net
APIs. Now almost all the APIs return OpError as a common error type
except Lookup, Resolve and Parse APIs. The Lookup, Resolve and Parse
APIs return more specific errors such as DNSError, AddrError or
ParseError.

An OpError may contain nested error information. For example, Dial may
return an OpError containing a DNSError, AddrError, unexposed type/value
or other package's type/value like the following:
OpError{/* dial info */, Err: &DNSError{}}
OpError{/* dial info */, Err: &AddrError{}}
OpError{/* dial info */, Err: <unexposed type or value>}
OpError{/* dial info */, Err: <other package's type or value>}

and Read and Write may return an OpError containing other OpError when
an application uses io.Copy or similar:
OpError{/* for io.Reader */, Err: &OpError{/* for io.Writer */}}

When an endpoint is created for connection-oriented byte-stream
protocols, Read may return an io.EOF when the connection is closed by
remote endpoint.

Fixes #4856.

A series of changes:
- net: fix inconsistent error values on Dial, Listen partially
  https://go.googlesource.com/go/+/89b7c66d0d14462fd7893be4290bdfe5f9063ae1
- net: fix inconsistent error values on Read
  https://go.googlesource.com/go/+/ec1144423f45e010c72363fe59291d43214b6e31
- net: fix inconsistent error values on Write
  https://go.googlesource.com/go/+/11b5f98bf0d5eb8854f735cc332c912725070214
- net: fix inconsistent error values on Close
  https://go.googlesource.com/go/+/310db63c5bc121e7bfccb494c01a6b91a257e7fc
- net: fix inconsistent error values on Accept
  https://go.googlesource.com/go/+/4540e162b1aefda8157372764ad3d290a414ef1d
- net: fix inconsistent error values on File
  https://go.googlesource.com/go/+/885111365ba0a74421059bfbd18f4c57c1e70332
- net: fix inconsistent error values on setters
  https://go.googlesource.com/go/+/2173a27903897c481b0a0daf3ca3e0a0685701db
- net: fix inconsistent error values on Interface
  https://go.googlesource.com/go/+/456cf0f22c93e1a6654980f4a48a564555f6c8a2
- net: fix inconsistent error values on Lookup
  https://go.googlesource.com/go/+/0fc582e87942b2e52bed751b6c56660ba99e9a7d
- net: add Source field to OpError
  https://go.googlesource.com/go/+/afd2d2b6df3ebfe99faf347030f15adfdf422fa0

Change-Id: Id678e369088dc9fbe9073cfe7ff8a8754a57d61f
Reviewed-on: https://go-review.googlesource.com/9236
Reviewed-by: Ian Lance Taylor <iant@golang.org>
27 files changed:
src/net/fd_plan9.go
src/net/fd_unix.go
src/net/fd_windows.go
src/net/file_plan9.go
src/net/file_unix.go
src/net/interface_bsd.go
src/net/interface_darwin.go
src/net/interface_freebsd.go
src/net/interface_linux.go
src/net/interface_windows.go
src/net/ip.go
src/net/ip_test.go
src/net/ipsock.go
src/net/ipsock_plan9.go
src/net/ipsock_posix.go
src/net/lookup_plan9.go
src/net/lookup_windows.go
src/net/mac.go
src/net/net.go
src/net/sendfile_dragonfly.go
src/net/sendfile_freebsd.go
src/net/sendfile_linux.go
src/net/sendfile_windows.go
src/net/sock_cloexec.go
src/net/sock_windows.go
src/net/sys_cloexec.go
src/net/tcpsockopt_windows.go

index 347829ce8e0b07cf87a32e23d3a9390ee9c2b7da..32766f53b58ea9ccd12eee4232249ee38dc751b2 100644 (file)
@@ -202,7 +202,7 @@ func (fd *netFD) file(f *os.File, s string) (*os.File, error) {
        dfd, err := syscall.Dup(int(f.Fd()), -1)
        syscall.ForkLock.RUnlock()
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("dup", err)
        }
        return os.NewFile(uintptr(dfd), s), nil
 }
index 4859d92c99bfcbbd934480b8f5464be65015c2d8..64e94fecf8a85c84dd085b94b0e1d624b97aa49e 100644 (file)
@@ -93,7 +93,7 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
                }
                fallthrough
        default:
-               return err
+               return os.NewSyscallError("connect", err)
        }
        if err := fd.init(); err != nil {
                return err
@@ -116,14 +116,14 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
                }
                nerr, err := getsockoptIntFunc(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
                if err != nil {
-                       return err
+                       return os.NewSyscallError("getsockopt", err)
                }
                switch err := syscall.Errno(nerr); err {
                case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
                case syscall.Errno(0), syscall.EISCONN:
                        return nil
                default:
-                       return err
+                       return os.NewSyscallError("getsockopt", err)
                }
        }
 }
@@ -205,7 +205,7 @@ func (fd *netFD) shutdown(how int) error {
                return err
        }
        defer fd.decref()
-       return syscall.Shutdown(fd.sysfd, how)
+       return os.NewSyscallError("shutdown", syscall.Shutdown(fd.sysfd, how))
 }
 
 func (fd *netFD) closeRead() error {
@@ -237,6 +237,9 @@ func (fd *netFD) Read(p []byte) (n int, err error) {
                err = fd.eofError(n, err)
                break
        }
+       if _, ok := err.(syscall.Errno); ok {
+               err = os.NewSyscallError("read", err)
+       }
        return
 }
 
@@ -261,6 +264,9 @@ func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
                err = fd.eofError(n, err)
                break
        }
+       if _, ok := err.(syscall.Errno); ok {
+               err = os.NewSyscallError("recvfrom", err)
+       }
        return
 }
 
@@ -285,6 +291,9 @@ func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S
                err = fd.eofError(n, err)
                break
        }
+       if _, ok := err.(syscall.Errno); ok {
+               err = os.NewSyscallError("recvmsg", err)
+       }
        return
 }
 
@@ -318,6 +327,9 @@ func (fd *netFD) Write(p []byte) (nn int, err error) {
                        break
                }
        }
+       if _, ok := err.(syscall.Errno); ok {
+               err = os.NewSyscallError("write", err)
+       }
        return nn, err
 }
 
@@ -341,6 +353,9 @@ func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
        if err == nil {
                n = len(p)
        }
+       if _, ok := err.(syscall.Errno); ok {
+               err = os.NewSyscallError("sendto", err)
+       }
        return
 }
 
@@ -364,6 +379,9 @@ func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob
        if err == nil {
                oobn = len(oob)
        }
+       if _, ok := err.(syscall.Errno); ok {
+               err = os.NewSyscallError("sendmsg", err)
+       }
        return
 }
 
@@ -381,13 +399,20 @@ func (fd *netFD) accept() (netfd *netFD, err error) {
        for {
                s, rsa, err = accept(fd.sysfd)
                if err != nil {
-                       if err == syscall.EAGAIN {
+                       nerr, ok := err.(*os.SyscallError)
+                       if !ok {
+                               return nil, err
+                       }
+                       switch nerr.Err {
+                       case syscall.EAGAIN:
                                if err = fd.pd.WaitRead(); err == nil {
                                        continue
                                }
-                       } else if err == syscall.ECONNABORTED {
-                               // This means that a socket on the listen queue was closed
-                               // before we Accept()ed it; it's a silly error, so try again.
+                       case syscall.ECONNABORTED:
+                               // This means that a socket on the
+                               // listen queue was closed before we
+                               // Accept()ed it; it's a silly error,
+                               // so try again.
                                continue
                        }
                        return nil, err
@@ -436,7 +461,7 @@ func dupCloseOnExec(fd int) (newfd int, err error) {
                        // from now on.
                        atomic.StoreInt32(&tryDupCloexec, 0)
                default:
-                       return -1, e1
+                       return -1, os.NewSyscallError("fcntl", e1)
                }
        }
        return dupCloseOnExecOld(fd)
@@ -449,7 +474,7 @@ func dupCloseOnExecOld(fd int) (newfd int, err error) {
        defer syscall.ForkLock.RUnlock()
        newfd, err = syscall.Dup(fd)
        if err != nil {
-               return -1, err
+               return -1, os.NewSyscallError("dup", err)
        }
        syscall.CloseOnExec(newfd)
        return
@@ -466,7 +491,7 @@ func (fd *netFD) dup() (f *os.File, err error) {
        // I/O will block the thread instead of letting us use the epoll server.
        // Everything will still work, just with more threads.
        if err = syscall.SetNonblock(ns, false); err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("setnonblock", err)
        }
 
        return os.NewFile(uintptr(ns), fd.name()), nil
index 654eb2ee05943f26f28d361563ecc655149f47b5..205daff9e4607ec22d56a460335c136906fb404d 100644 (file)
@@ -38,7 +38,7 @@ func sysInit() {
        var d syscall.WSAData
        e := syscall.WSAStartup(uint32(0x202), &d)
        if e != nil {
-               initErr = os.NewSyscallError("WSAStartup", e)
+               initErr = os.NewSyscallError("wsastartup", e)
        }
        canCancelIO = syscall.LoadCancelIoEx() == nil
        if syscall.LoadGetAddrInfo() == nil {
@@ -297,7 +297,7 @@ func (fd *netFD) init() error {
                size := uint32(unsafe.Sizeof(flag))
                err := syscall.WSAIoctl(fd.sysfd, syscall.SIO_UDP_CONNRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0)
                if err != nil {
-                       return os.NewSyscallError("WSAIoctl", err)
+                       return os.NewSyscallError("wsaioctl", err)
                }
        }
        fd.rop.mode = 'r'
@@ -331,7 +331,7 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
                defer fd.setWriteDeadline(noDeadline)
        }
        if !canUseConnectEx(fd.net) {
-               return connectFunc(fd.sysfd, ra)
+               return os.NewSyscallError("connect", connectFunc(fd.sysfd, ra))
        }
        // ConnectEx windows API requires an unconnected, previously bound socket.
        if la == nil {
@@ -344,7 +344,7 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
                        panic("unexpected type in connect")
                }
                if err := syscall.Bind(fd.sysfd, la); err != nil {
-                       return err
+                       return os.NewSyscallError("bind", err)
                }
        }
        // Call ConnectEx API.
@@ -354,10 +354,13 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
                return connectExFunc(o.fd.sysfd, o.sa, nil, 0, nil, &o.o)
        })
        if err != nil {
+               if _, ok := err.(syscall.Errno); ok {
+                       err = os.NewSyscallError("connectex", err)
+               }
                return err
        }
        // Refresh socket properties.
-       return syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
+       return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd))))
 }
 
 func (fd *netFD) destroy() {
@@ -461,7 +464,11 @@ func (fd *netFD) Read(buf []byte) (int, error) {
        if raceenabled {
                raceAcquire(unsafe.Pointer(&ioSync))
        }
-       return n, fd.eofError(n, err)
+       err = fd.eofError(n, err)
+       if _, ok := err.(syscall.Errno); ok {
+               err = os.NewSyscallError("wsarecv", err)
+       }
+       return n, err
 }
 
 func (fd *netFD) readFrom(buf []byte) (int, syscall.Sockaddr, error) {
@@ -482,11 +489,14 @@ func (fd *netFD) readFrom(buf []byte) (int, syscall.Sockaddr, error) {
                return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
        })
        err = fd.eofError(n, err)
+       if _, ok := err.(syscall.Errno); ok {
+               err = os.NewSyscallError("wsarecvfrom", err)
+       }
        if err != nil {
                return n, nil, err
        }
        sa, _ := o.rsa.Sockaddr()
-       return n, sa, err
+       return n, sa, nil
 }
 
 func (fd *netFD) Write(buf []byte) (int, error) {
@@ -502,6 +512,9 @@ func (fd *netFD) Write(buf []byte) (int, error) {
        n, err := wsrv.ExecIO(o, "WSASend", func(o *operation) error {
                return syscall.WSASend(o.fd.sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil)
        })
+       if _, ok := err.(syscall.Errno); ok {
+               err = os.NewSyscallError("wsasend", err)
+       }
        return n, err
 }
 
@@ -519,6 +532,9 @@ func (fd *netFD) writeTo(buf []byte, sa syscall.Sockaddr) (int, error) {
        n, err := wsrv.ExecIO(o, "WSASendto", func(o *operation) error {
                return syscall.WSASendto(o.fd.sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
        })
+       if _, ok := err.(syscall.Errno); ok {
+               err = os.NewSyscallError("wsasendto", err)
+       }
        return n, err
 }
 
@@ -548,6 +564,9 @@ func (fd *netFD) acceptOne(rawsa []syscall.RawSockaddrAny, o *operation) (*netFD
        })
        if err != nil {
                netfd.Close()
+               if _, ok := err.(syscall.Errno); ok {
+                       err = os.NewSyscallError("acceptex", err)
+               }
                return nil, err
        }
 
@@ -555,7 +574,7 @@ func (fd *netFD) acceptOne(rawsa []syscall.RawSockaddrAny, o *operation) (*netFD
        err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
        if err != nil {
                netfd.Close()
-               return nil, err
+               return nil, os.NewSyscallError("setsockopt", err)
        }
 
        return netfd, nil
@@ -581,7 +600,11 @@ func (fd *netFD) accept() (*netFD, error) {
                // before AcceptEx could complete. These errors relate to new
                // connection, not to AcceptEx, so ignore broken connection and
                // try AcceptEx again for more connections.
-               errno, ok := err.(syscall.Errno)
+               nerr, ok := err.(*os.SyscallError)
+               if !ok {
+                       return nil, err
+               }
+               errno, ok := nerr.Err.(syscall.Errno)
                if !ok {
                        return nil, err
                }
index 0aa6c32d06b511252734a82155412b612bbfe1b2..892775a024f45667bd96f4b6206a3a6df80686a8 100644 (file)
@@ -39,7 +39,7 @@ func newFileFD(f *os.File) (net *netFD, err error) {
 
        path, err := syscall.Fd2path(int(f.Fd()))
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("fd2path", err)
        }
        comp := splitAtBytes(path, "/")
        n := len(comp)
@@ -54,7 +54,7 @@ func newFileFD(f *os.File) (net *netFD, err error) {
                fd, err := syscall.Dup(int(f.Fd()), -1)
                syscall.ForkLock.RUnlock()
                if err != nil {
-                       return nil, err
+                       return nil, os.NewSyscallError("dup", err)
                }
                defer close(fd)
 
index 98ceea1d55caa26796de5e371ef6951c4efb602c..147ca1ed9575c8bffae183350c9fcb829b395055 100644 (file)
@@ -19,13 +19,13 @@ func newFileFD(f *os.File) (*netFD, error) {
 
        if err = syscall.SetNonblock(fd, true); err != nil {
                closeFunc(fd)
-               return nil, err
+               return nil, os.NewSyscallError("setnonblock", err)
        }
 
        sotype, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE)
        if err != nil {
                closeFunc(fd)
-               return nil, err
+               return nil, os.NewSyscallError("getsockopt", err)
        }
 
        family := syscall.AF_UNSPEC
index 01a67c69a15c47410f0b6aa7eaf697aa274ef0cb..208f37f9fd34aa45d862f0886b78fb376d44dafd 100644 (file)
@@ -7,6 +7,7 @@
 package net
 
 import (
+       "os"
        "syscall"
        "unsafe"
 )
@@ -17,11 +18,11 @@ import (
 func interfaceTable(ifindex int) ([]Interface, error) {
        tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("routerib", err)
        }
        msgs, err := syscall.ParseRoutingMessage(tab)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("parseroutingmessage", err)
        }
        return parseInterfaceTable(ifindex, msgs)
 }
@@ -50,7 +51,7 @@ loop:
 func newLink(m *syscall.InterfaceMessage) (*Interface, error) {
        sas, err := syscall.ParseRoutingSockaddr(m)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("parseroutingsockaddr", err)
        }
        ifi := &Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)}
        sa, _ := sas[syscall.RTAX_IFP].(*syscall.SockaddrDatalink)
@@ -103,11 +104,11 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
        }
        tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, index)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("routerib", err)
        }
        msgs, err := syscall.ParseRoutingMessage(tab)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("parseroutingmessage", err)
        }
        var ift []Interface
        if index == 0 {
@@ -144,7 +145,7 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
 func newAddr(ifi *Interface, m *syscall.InterfaceAddrMessage) (*IPNet, error) {
        sas, err := syscall.ParseRoutingSockaddr(m)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("parseroutingsockaddr", err)
        }
        ifa := &IPNet{}
        switch sa := sas[syscall.RTAX_NETMASK].(type) {
index bda6ff9a57d69b24612ee40c3ec6c4d03ce38fee..b7a333849d142f48322ab880de91413cdddb7e17 100644 (file)
@@ -4,18 +4,21 @@
 
 package net
 
-import "syscall"
+import (
+       "os"
+       "syscall"
+)
 
 // interfaceMulticastAddrTable returns addresses for a specific
 // interface.
 func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
        tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST2, ifi.Index)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("routerib", err)
        }
        msgs, err := syscall.ParseRoutingMessage(tab)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("parseroutingmessage", err)
        }
        var ifmat []Addr
        for _, m := range msgs {
@@ -38,7 +41,7 @@ func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
 func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) (*IPAddr, error) {
        sas, err := syscall.ParseRoutingSockaddr(m)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("parseroutingsockaddr", err)
        }
        switch sa := sas[syscall.RTAX_IFA].(type) {
        case *syscall.SockaddrInet4:
index c759db4720e583e6c054e7527c210574610e9ad2..c42d90b7403e8b858673ff01b3971b72d975dc81 100644 (file)
@@ -4,18 +4,21 @@
 
 package net
 
-import "syscall"
+import (
+       "os"
+       "syscall"
+)
 
 // interfaceMulticastAddrTable returns addresses for a specific
 // interface.
 func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
        tab, err := syscall.RouteRIB(syscall.NET_RT_IFMALIST, ifi.Index)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("routerib", err)
        }
        msgs, err := syscall.ParseRoutingMessage(tab)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("parseroutingmessage", err)
        }
        var ifmat []Addr
        for _, m := range msgs {
@@ -38,7 +41,7 @@ func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
 func newMulticastAddr(ifi *Interface, m *syscall.InterfaceMulticastAddrMessage) (*IPAddr, error) {
        sas, err := syscall.ParseRoutingSockaddr(m)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("parseroutingsockaddr", err)
        }
        switch sa := sas[syscall.RTAX_IFA].(type) {
        case *syscall.SockaddrInet4:
index 3c117ea2f55240474cbc4b285cf18bbacf15cc7e..6551a3562e97aee4904a8baad8d94e7a165b5994 100644 (file)
@@ -5,6 +5,7 @@
 package net
 
 import (
+       "os"
        "syscall"
        "unsafe"
 )
@@ -15,11 +16,11 @@ import (
 func interfaceTable(ifindex int) ([]Interface, error) {
        tab, err := syscall.NetlinkRIB(syscall.RTM_GETLINK, syscall.AF_UNSPEC)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("netlinkrib", err)
        }
        msgs, err := syscall.ParseNetlinkMessage(tab)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("parsenetlinkmessage", err)
        }
        var ift []Interface
 loop:
@@ -32,7 +33,7 @@ loop:
                        if ifindex == 0 || ifindex == int(ifim.Index) {
                                attrs, err := syscall.ParseNetlinkRouteAttr(&m)
                                if err != nil {
-                                       return nil, err
+                                       return nil, os.NewSyscallError("parsenetlinkrouteattr", err)
                                }
                                ift = append(ift, *newLink(ifim, attrs))
                                if ifindex == int(ifim.Index) {
@@ -119,11 +120,11 @@ func linkFlags(rawFlags uint32) Flags {
 func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
        tab, err := syscall.NetlinkRIB(syscall.RTM_GETADDR, syscall.AF_UNSPEC)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("netlinkrib", err)
        }
        msgs, err := syscall.ParseNetlinkMessage(tab)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("parsenetlinkmessage", err)
        }
        var ift []Interface
        if ifi == nil {
@@ -159,7 +160,7 @@ loop:
                                }
                                attrs, err := syscall.ParseNetlinkRouteAttr(&m)
                                if err != nil {
-                                       return nil, err
+                                       return nil, os.NewSyscallError("parsenetlinkrouteattr", err)
                                }
                                ifa := newAddr(ifi, ifam, attrs)
                                if ifa != nil {
index 83870efb10780bc416059bb3f35c0866022b18e8..e25c1ed560b5f82a24682be0c5028c5dbc6a0157 100644 (file)
@@ -6,6 +6,7 @@ package net
 
 import (
        "internal/syscall/windows"
+       "os"
        "syscall"
        "unsafe"
 )
@@ -26,7 +27,7 @@ func getAdapters() (*windows.IpAdapterAddresses, error) {
                        break
                }
                if err.(syscall.Errno) != syscall.ERROR_BUFFER_OVERFLOW {
-                       return nil, err
+                       return nil, os.NewSyscallError("getadaptersaddresses", err)
                }
        }
        return &addrs[0], nil
@@ -44,7 +45,7 @@ func getInterfaceInfos() ([]syscall.InterfaceInfo, error) {
        size := uint32(unsafe.Sizeof(iia))
        err = syscall.WSAIoctl(s, syscall.SIO_GET_INTERFACE_LIST, nil, 0, (*byte)(unsafe.Pointer(&iia[0])), size, &ret, nil, 0)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("wsaioctl", err)
        }
        iilen := ret / uint32(unsafe.Sizeof(iia[0]))
        return iia[:iilen-1], nil
index a554165af767f1519f2ae1b33ed149a09936233c..a7f45642e37fbabb4448c23756fea1311ec5ff1b 100644 (file)
@@ -12,8 +12,6 @@
 
 package net
 
-import "errors"
-
 // IP address lengths (bytes).
 const (
        IPv4len = 4
@@ -331,7 +329,7 @@ func (ip IP) MarshalText() ([]byte, error) {
                return []byte(""), nil
        }
        if len(ip) != IPv4len && len(ip) != IPv6len {
-               return nil, errors.New("invalid IP address")
+               return nil, &AddrError{Err: "invalid IP address", Addr: ip.String()}
        }
        return []byte(ip.String()), nil
 }
@@ -346,7 +344,7 @@ func (ip *IP) UnmarshalText(text []byte) error {
        s := string(text)
        x := ParseIP(s)
        if x == nil {
-               return &ParseError{"IP address", s}
+               return &ParseError{Type: "IP address", Text: s}
        }
        *ip = x
        return nil
@@ -633,16 +631,6 @@ func parseIPv6(s string, zoneAllowed bool) (ip IP, zone string) {
        return ip, zone
 }
 
-// A ParseError represents a malformed text string and the type of string that was expected.
-type ParseError struct {
-       Type string
-       Text string
-}
-
-func (e *ParseError) Error() string {
-       return "invalid " + e.Type + ": " + e.Text
-}
-
 // ParseIP parses s as an IP address, returning the result.
 // The string s can be in dotted decimal ("74.125.19.99")
 // or IPv6 ("2001:4860:0:2001::68") form.
@@ -671,7 +659,7 @@ func ParseIP(s string) IP {
 func ParseCIDR(s string) (IP, *IPNet, error) {
        i := byteIndex(s, '/')
        if i < 0 {
-               return nil, nil, &ParseError{"CIDR address", s}
+               return nil, nil, &ParseError{Type: "CIDR address", Text: s}
        }
        addr, mask := s[:i], s[i+1:]
        iplen := IPv4len
@@ -682,7 +670,7 @@ func ParseCIDR(s string) (IP, *IPNet, error) {
        }
        n, i, ok := dtoi(mask, 0)
        if ip == nil || !ok || i != len(mask) || n < 0 || n > 8*iplen {
-               return nil, nil, &ParseError{"CIDR address", s}
+               return nil, nil, &ParseError{Type: "CIDR address", Text: s}
        }
        m := CIDRMask(n, 8*iplen)
        return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
index 1215b69d0289bcffa05b9364bf8eabe00ccb3bcf..24f67cac9750aef6f085815d4458fa57534d7fd9 100644 (file)
@@ -194,10 +194,10 @@ var parseCIDRTests = []struct {
        {"abcd:2345::/24", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2300::"), Mask: IPMask(ParseIP("ffff:ff00::"))}, nil},
        {"2001:DB8::/48", ParseIP("2001:DB8::"), &IPNet{IP: ParseIP("2001:DB8::"), Mask: IPMask(ParseIP("ffff:ffff:ffff::"))}, nil},
        {"2001:DB8::1/48", ParseIP("2001:DB8::1"), &IPNet{IP: ParseIP("2001:DB8::"), Mask: IPMask(ParseIP("ffff:ffff:ffff::"))}, nil},
-       {"192.168.1.1/255.255.255.0", nil, nil, &ParseError{"CIDR address", "192.168.1.1/255.255.255.0"}},
-       {"192.168.1.1/35", nil, nil, &ParseError{"CIDR address", "192.168.1.1/35"}},
-       {"2001:db8::1/-1", nil, nil, &ParseError{"CIDR address", "2001:db8::1/-1"}},
-       {"", nil, nil, &ParseError{"CIDR address", ""}},
+       {"192.168.1.1/255.255.255.0", nil, nil, &ParseError{Type: "CIDR address", Text: "192.168.1.1/255.255.255.0"}},
+       {"192.168.1.1/35", nil, nil, &ParseError{Type: "CIDR address", Text: "192.168.1.1/35"}},
+       {"2001:db8::1/-1", nil, nil, &ParseError{Type: "CIDR address", Text: "2001:db8::1/-1"}},
+       {"", nil, nil, &ParseError{Type: "CIDR address", Text: ""}},
 }
 
 func TestParseCIDR(t *testing.T) {
index c09faa763ed9df473653bf7ac2d0712df0aab23c..6e75c33d53471e91fa276736a91420bab316497e 100644 (file)
@@ -122,7 +122,7 @@ func SplitHostPort(hostport string) (host, port string, err error) {
                // Expect the first ']' just before the last ':'.
                end := byteIndex(hostport, ']')
                if end < 0 {
-                       err = &AddrError{"missing ']' in address", hostport}
+                       err = &AddrError{Err: "missing ']' in address", Addr: hostport}
                        return
                }
                switch end + 1 {
@@ -151,11 +151,11 @@ func SplitHostPort(hostport string) (host, port string, err error) {
                }
        }
        if byteIndex(hostport[j:], '[') >= 0 {
-               err = &AddrError{"unexpected '[' in address", hostport}
+               err = &AddrError{Err: "unexpected '[' in address", Addr: hostport}
                return
        }
        if byteIndex(hostport[k:], ']') >= 0 {
-               err = &AddrError{"unexpected ']' in address", hostport}
+               err = &AddrError{Err: "unexpected ']' in address", Addr: hostport}
                return
        }
 
@@ -163,15 +163,15 @@ func SplitHostPort(hostport string) (host, port string, err error) {
        return
 
 missingPort:
-       err = &AddrError{"missing port in address", hostport}
+       err = &AddrError{Err: "missing port in address", Addr: hostport}
        return
 
 tooManyColons:
-       err = &AddrError{"too many colons in address", hostport}
+       err = &AddrError{Err: "too many colons in address", Addr: hostport}
        return
 
 missingBrackets:
-       err = &AddrError{"missing brackets in address", hostport}
+       err = &AddrError{Err: "missing brackets in address", Addr: hostport}
        return
 }
 
index 11b6b32e0b41fee364b69e39bd2c32f48c24674d..72d640d9238e681b478e033f09f27843d9f8fd45 100644 (file)
@@ -7,7 +7,6 @@
 package net
 
 import (
-       "errors"
        "os"
        "syscall"
 )
@@ -60,15 +59,15 @@ func parsePlan9Addr(s string) (ip IP, iport int, err error) {
        if i >= 0 {
                addr = ParseIP(s[:i])
                if addr == nil {
-                       return nil, 0, errors.New("parsing IP failed")
+                       return nil, 0, &ParseError{Type: "IP address", Text: s}
                }
        }
        p, _, ok := dtoi(s[i+1:], 0)
        if !ok {
-               return nil, 0, errors.New("parsing port failed")
+               return nil, 0, &ParseError{Type: "port", Text: s}
        }
        if p < 0 || p > 0xFFFF {
-               return nil, 0, &AddrError{"invalid port", string(p)}
+               return nil, 0, &AddrError{Err: "invalid port", Addr: string(p)}
        }
        return addr, p, nil
 }
@@ -95,7 +94,7 @@ func readPlan9Addr(proto, filename string) (addr Addr, err error) {
        case "udp":
                addr = &UDPAddr{IP: ip, Port: port}
        default:
-               return nil, errors.New("unknown protocol " + proto)
+               return nil, UnknownNetworkError(proto)
        }
        return addr, nil
 }
index 7597a92f6fa90435b73f28f37f832fec64aef0e5..56b9872fd1e6649e5dd26d7c53a3fc31164755ec 100644 (file)
@@ -144,7 +144,7 @@ func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, e
                        ip = IPv4zero
                }
                if ip = ip.To4(); ip == nil {
-                       return nil, InvalidAddrError("non-IPv4 address")
+                       return nil, &AddrError{Err: "non-IPv4 address", Addr: ip.String()}
                }
                sa := new(syscall.SockaddrInet4)
                for i := 0; i < IPv4len; i++ {
@@ -163,7 +163,7 @@ func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, e
                        ip = IPv6zero
                }
                if ip = ip.To16(); ip == nil {
-                       return nil, InvalidAddrError("non-IPv6 address")
+                       return nil, &AddrError{Err: "non-IPv6 address", Addr: ip.String()}
                }
                sa := new(syscall.SockaddrInet6)
                for i := 0; i < IPv6len; i++ {
@@ -173,5 +173,5 @@ func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, e
                sa.ZoneId = uint32(zoneToInt(zone))
                return sa, nil
        }
-       return nil, InvalidAddrError("unexpected socket family")
+       return nil, &AddrError{Err: "invalid address family", Addr: ip.String()}
 }
index 73abbad93be460ad2aaedfe05419f17a86ae9df9..c6274640bb7d251434f093474a1f4c65661202a4 100644 (file)
@@ -101,19 +101,18 @@ func lookupProtocol(name string) (proto int, err error) {
        if err != nil {
                return 0, err
        }
-       unknownProtoError := errors.New("unknown IP protocol specified: " + name)
        if len(lines) == 0 {
-               return 0, unknownProtoError
+               return 0, UnknownNetworkError(name)
        }
        f := getFields(lines[0])
        if len(f) < 2 {
-               return 0, unknownProtoError
+               return 0, UnknownNetworkError(name)
        }
        s := f[1]
        if n, _, ok := dtoi(s, byteIndex(s, '=')+1); ok {
                return n, nil
        }
-       return 0, unknownProtoError
+       return 0, UnknownNetworkError(name)
 }
 
 func lookupHost(host string) (addrs []string, err error) {
@@ -173,7 +172,7 @@ func lookupPort(network, service string) (port int, err error) {
        if err != nil {
                return
        }
-       unknownPortError := &AddrError{"unknown port", network + "/" + service}
+       unknownPortError := &AddrError{Err: "unknown port", Addr: network + "/" + service}
        if len(lines) == 0 {
                return 0, unknownPortError
        }
index 7ad393ab690b2e8854c960d1d4cb2ca5a11b91f4..1b6d392f660c8e1b7a98fbe9663de70715d054a6 100644 (file)
@@ -5,6 +5,7 @@
 package net
 
 import (
+       "os"
        "runtime"
        "syscall"
        "unsafe"
@@ -18,7 +19,7 @@ var (
 func getprotobyname(name string) (proto int, err error) {
        p, err := syscall.GetProtoByName(name)
        if err != nil {
-               return 0, err
+               return 0, os.NewSyscallError("getorotobyname", err)
        }
        return int(p.Proto), nil
 }
@@ -66,7 +67,7 @@ func gethostbyname(name string) (addrs []IPAddr, err error) {
        // caller already acquired thread
        h, err := syscall.GetHostByName(name)
        if err != nil {
-               return nil, err
+               return nil, os.NewSyscallError("gethostbyname", err)
        }
        switch h.AddrType {
        case syscall.AF_INET:
@@ -116,7 +117,7 @@ func newLookupIP(name string) ([]IPAddr, error) {
        var result *syscall.AddrinfoW
        e := syscall.GetAddrInfoW(syscall.StringToUTF16Ptr(name), nil, &hints, &result)
        if e != nil {
-               return nil, &DNSError{Err: e.Error(), Name: name}
+               return nil, &DNSError{Err: os.NewSyscallError("getaddrinfow", e).Error(), Name: name}
        }
        defer syscall.FreeAddrInfoW(result)
        addrs := make([]IPAddr, 0, 5)
@@ -148,7 +149,7 @@ func getservbyname(network, service string) (int, error) {
        }
        s, err := syscall.GetServByName(service, network)
        if err != nil {
-               return 0, err
+               return 0, os.NewSyscallError("getservbyname", err)
        }
        return int(syscall.Ntohs(s.Port)), nil
 }
@@ -194,7 +195,7 @@ func newLookupPort(network, service string) (int, error) {
        var result *syscall.AddrinfoW
        e := syscall.GetAddrInfoW(nil, syscall.StringToUTF16Ptr(service), &hints, &result)
        if e != nil {
-               return 0, &DNSError{Err: e.Error(), Name: network + "/" + service}
+               return 0, &DNSError{Err: os.NewSyscallError("getaddrinfow", e).Error(), Name: network + "/" + service}
        }
        defer syscall.FreeAddrInfoW(result)
        if result == nil {
@@ -226,7 +227,7 @@ func lookupCNAME(name string) (string, error) {
                return name, nil
        }
        if e != nil {
-               return "", &DNSError{Err: e.Error(), Name: name}
+               return "", &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: name}
        }
        defer syscall.DnsRecordListFree(r, 1)
 
@@ -247,7 +248,7 @@ func lookupSRV(service, proto, name string) (string, []*SRV, error) {
        var r *syscall.DNSRecord
        e := syscall.DnsQuery(target, syscall.DNS_TYPE_SRV, 0, nil, &r, nil)
        if e != nil {
-               return "", nil, &DNSError{Err: e.Error(), Name: target}
+               return "", nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: target}
        }
        defer syscall.DnsRecordListFree(r, 1)
 
@@ -266,7 +267,7 @@ func lookupMX(name string) ([]*MX, error) {
        var r *syscall.DNSRecord
        e := syscall.DnsQuery(name, syscall.DNS_TYPE_MX, 0, nil, &r, nil)
        if e != nil {
-               return nil, &DNSError{Err: e.Error(), Name: name}
+               return nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: name}
        }
        defer syscall.DnsRecordListFree(r, 1)
 
@@ -285,7 +286,7 @@ func lookupNS(name string) ([]*NS, error) {
        var r *syscall.DNSRecord
        e := syscall.DnsQuery(name, syscall.DNS_TYPE_NS, 0, nil, &r, nil)
        if e != nil {
-               return nil, &DNSError{Err: e.Error(), Name: name}
+               return nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: name}
        }
        defer syscall.DnsRecordListFree(r, 1)
 
@@ -303,7 +304,7 @@ func lookupTXT(name string) ([]string, error) {
        var r *syscall.DNSRecord
        e := syscall.DnsQuery(name, syscall.DNS_TYPE_TEXT, 0, nil, &r, nil)
        if e != nil {
-               return nil, &DNSError{Err: e.Error(), Name: name}
+               return nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: name}
        }
        defer syscall.DnsRecordListFree(r, 1)
 
@@ -328,7 +329,7 @@ func lookupAddr(addr string) ([]string, error) {
        var r *syscall.DNSRecord
        e := syscall.DnsQuery(arpa, syscall.DNS_TYPE_PTR, 0, nil, &r, nil)
        if e != nil {
-               return nil, &DNSError{Err: e.Error(), Name: addr}
+               return nil, &DNSError{Err: os.NewSyscallError("dnsquery", e).Error(), Name: addr}
        }
        defer syscall.DnsRecordListFree(r, 1)
 
index d616b1f689f46db6ec9ca3b025713ba362523400..8594a9146ae681772e1cbc1f5032d03eab2d0278 100644 (file)
@@ -2,12 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// MAC address manipulations
-
 package net
 
-import "errors"
-
 const hexDigit = "0123456789abcdef"
 
 // A HardwareAddr represents a physical hardware address.
@@ -82,5 +78,5 @@ func ParseMAC(s string) (hw HardwareAddr, err error) {
        return hw, nil
 
 error:
-       return nil, errors.New("invalid MAC address: " + s)
+       return nil, &AddrError{Err: "invalid MAC address", Addr: s}
 }
index 589f21f5827b14f6860d2d016580444ca91c91f6..fbeac81d2707c75f71f6e6de56a4446aa821678d 100644 (file)
@@ -244,13 +244,6 @@ func (c *conn) File() (f *os.File, err error) {
        return
 }
 
-// An Error represents a network error.
-type Error interface {
-       error
-       Timeout() bool   // Is the error a timeout?
-       Temporary() bool // Is the error temporary?
-}
-
 // PacketConn is a generic packet-oriented network connection.
 //
 // Multiple goroutines may invoke methods on a PacketConn simultaneously.
@@ -314,6 +307,13 @@ type Listener interface {
        Addr() Addr
 }
 
+// An Error represents a network error.
+type Error interface {
+       error
+       Timeout() bool   // Is the error a timeout?
+       Temporary() bool // Is the error temporary?
+}
+
 // Various errors contained in OpError.
 var (
        // For connection setup and write operations.
@@ -377,15 +377,6 @@ func (e *OpError) Error() string {
        return s
 }
 
-type temporary interface {
-       Temporary() bool
-}
-
-func (e *OpError) Temporary() bool {
-       t, ok := e.Err.(temporary)
-       return ok && t.Temporary()
-}
-
 var noDeadline = time.Time{}
 
 type timeout interface {
@@ -393,16 +384,45 @@ type timeout interface {
 }
 
 func (e *OpError) Timeout() bool {
+       if ne, ok := e.Err.(*os.SyscallError); ok {
+               t, ok := ne.Err.(timeout)
+               return ok && t.Timeout()
+       }
        t, ok := e.Err.(timeout)
        return ok && t.Timeout()
 }
 
+type temporary interface {
+       Temporary() bool
+}
+
+func (e *OpError) Temporary() bool {
+       if ne, ok := e.Err.(*os.SyscallError); ok {
+               t, ok := ne.Err.(temporary)
+               return ok && t.Temporary()
+       }
+       t, ok := e.Err.(temporary)
+       return ok && t.Temporary()
+}
+
 type timeoutError struct{}
 
 func (e *timeoutError) Error() string   { return "i/o timeout" }
 func (e *timeoutError) Timeout() bool   { return true }
 func (e *timeoutError) Temporary() bool { return true }
 
+// A ParseError is the error type of literal network address parsers.
+type ParseError struct {
+       // Type is the type of string that was expected, such as
+       // "IP address", "CIDR address".
+       Type string
+
+       // Text is the malformed text string.
+       Text string
+}
+
+func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text }
+
 type AddrError struct {
        Err  string
        Addr string
@@ -419,14 +439,14 @@ func (e *AddrError) Error() string {
        return s
 }
 
-func (e *AddrError) Temporary() bool { return false }
 func (e *AddrError) Timeout() bool   { return false }
+func (e *AddrError) Temporary() bool { return false }
 
 type UnknownNetworkError string
 
 func (e UnknownNetworkError) Error() string   { return "unknown network " + string(e) }
-func (e UnknownNetworkError) Temporary() bool { return false }
 func (e UnknownNetworkError) Timeout() bool   { return false }
+func (e UnknownNetworkError) Temporary() bool { return false }
 
 type InvalidAddrError string
 
index a0025b6ab6cea8b0acd4e03e13afa4e65540e82a..939a9a94666dca1795d4b35f08c8aa3a2efcf912 100644 (file)
@@ -99,5 +99,8 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
        if lr != nil {
                lr.N = remain
        }
+       if err != nil {
+               err = os.NewSyscallError("sendfile", err)
+       }
        return written, err, written > 0
 }
index a0324a328924c7c22548cd77dfaf24936a1f07b4..9b423cbb7ba9919a93667af78ff71d52b5f0e617 100644 (file)
@@ -99,5 +99,8 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
        if lr != nil {
                lr.N = remain
        }
+       if err != nil {
+               err = os.NewSyscallError("sendfile", err)
+       }
        return written, err, written > 0
 }
index e76828d053ec0c28bdba967446998959e95329cf..6480cf573e092775bc7846c16b70e4b9a1f0a835 100644 (file)
@@ -72,5 +72,8 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
        if lr != nil {
                lr.N = remain
        }
+       if err != nil {
+               err = os.NewSyscallError("sendfile", err)
+       }
        return written, err, written > 0
 }
index b128ba27b008fc51737868a2015dadd47da95e43..f3f3b54b886b034b6a7d218d377d0177270bc51d 100644 (file)
@@ -46,7 +46,7 @@ func sendFile(fd *netFD, r io.Reader) (written int64, err error, handled bool) {
                return syscall.TransmitFile(o.fd.sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
        })
        if err != nil {
-               return 0, err, false
+               return 0, os.NewSyscallError("transmitfile", err), false
        }
        if lr != nil {
                lr.N -= int64(done)
index 842d7d553882997b741bb44eb49c7cf50d60aa13..616a101eacb5086d8772a8c8e64d3e08fec5da9a 100644 (file)
@@ -9,7 +9,10 @@
 
 package net
 
-import "syscall"
+import (
+       "os"
+       "syscall"
+)
 
 // Wrapper around the socket system call that marks the returned file
 // descriptor as nonblocking and close-on-exec.
@@ -20,8 +23,12 @@ func sysSocket(family, sotype, proto int) (int, error) {
        // introduced in 10 kernel. If we get an EINVAL error on Linux
        // or EPROTONOSUPPORT error on FreeBSD, fall back to using
        // socket without them.
-       if err == nil || (err != syscall.EPROTONOSUPPORT && err != syscall.EINVAL) {
-               return s, err
+       switch err {
+       case nil:
+               return s, nil
+       default:
+               return -1, os.NewSyscallError("socket", err)
+       case syscall.EPROTONOSUPPORT, syscall.EINVAL:
        }
 
        // See ../syscall/exec_unix.go for description of ForkLock.
@@ -32,11 +39,11 @@ func sysSocket(family, sotype, proto int) (int, error) {
        }
        syscall.ForkLock.RUnlock()
        if err != nil {
-               return -1, err
+               return -1, os.NewSyscallError("socket", err)
        }
        if err = syscall.SetNonblock(s, true); err != nil {
                closeFunc(s)
-               return -1, err
+               return -1, os.NewSyscallError("setnonblock", err)
        }
        return s, nil
 }
@@ -50,8 +57,10 @@ func accept(s int) (int, syscall.Sockaddr, error) {
        // get an ENOSYS error on both Linux and FreeBSD, or EINVAL
        // error on Linux, fall back to using accept.
        switch err {
-       default: // nil and errors other than the ones listed
-               return ns, sa, err
+       case nil:
+               return ns, sa, nil
+       default: // errors other than the ones listed
+               return -1, sa, os.NewSyscallError("accept4", err)
        case syscall.ENOSYS: // syscall missing
        case syscall.EINVAL: // some Linux use this instead of ENOSYS
        case syscall.EACCES: // some Linux use this instead of ENOSYS
@@ -68,11 +77,11 @@ func accept(s int) (int, syscall.Sockaddr, error) {
                syscall.CloseOnExec(ns)
        }
        if err != nil {
-               return -1, nil, err
+               return -1, nil, os.NewSyscallError("accept", err)
        }
        if err = syscall.SetNonblock(ns, true); err != nil {
                closeFunc(ns)
-               return -1, nil, err
+               return -1, nil, os.NewSyscallError("setnonblock", err)
        }
        return ns, sa, nil
 }
index 591861f443892200cf5c33d1e42022239e19a024..888e70bb8e94b06e7a818e23c3cc9c009fba260e 100644 (file)
@@ -4,7 +4,10 @@
 
 package net
 
-import "syscall"
+import (
+       "os"
+       "syscall"
+)
 
 func maxListenerBacklog() int {
        // TODO: Implement this
@@ -20,5 +23,8 @@ func sysSocket(family, sotype, proto int) (syscall.Handle, error) {
                syscall.CloseOnExec(s)
        }
        syscall.ForkLock.RUnlock()
-       return s, err
+       if err != nil {
+               return syscall.InvalidHandle, os.NewSyscallError("socket", err)
+       }
+       return s, nil
 }
index 5a631aa56d22e17347ae153929dc2fc6430630e1..ba266e6534cbc7df02b5c68fe36cfd92e8d5b3f5 100644 (file)
@@ -9,7 +9,10 @@
 
 package net
 
-import "syscall"
+import (
+       "os"
+       "syscall"
+)
 
 // Wrapper around the socket system call that marks the returned file
 // descriptor as nonblocking and close-on-exec.
@@ -22,11 +25,11 @@ func sysSocket(family, sotype, proto int) (int, error) {
        }
        syscall.ForkLock.RUnlock()
        if err != nil {
-               return -1, err
+               return -1, os.NewSyscallError("socket", err)
        }
        if err = syscall.SetNonblock(s, true); err != nil {
                closeFunc(s)
-               return -1, err
+               return -1, os.NewSyscallError("setnonblock", err)
        }
        return s, nil
 }
@@ -44,11 +47,11 @@ func accept(s int) (int, syscall.Sockaddr, error) {
                syscall.CloseOnExec(ns)
        }
        if err != nil {
-               return -1, nil, err
+               return -1, nil, os.NewSyscallError("accept", err)
        }
        if err = syscall.SetNonblock(ns, true); err != nil {
                closeFunc(ns)
-               return -1, nil, err
+               return -1, nil, os.NewSyscallError("setnonblock", err)
        }
        return ns, sa, nil
 }
index 091f5233f20826bcffd5bb9b43bb98a0674f272b..ae2d7c8f182fc4bf28f62e7c717786c45c021a3f 100644 (file)
@@ -28,5 +28,5 @@ func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
        ret := uint32(0)
        size := uint32(unsafe.Sizeof(ka))
        err := syscall.WSAIoctl(fd.sysfd, syscall.SIO_KEEPALIVE_VALS, (*byte)(unsafe.Pointer(&ka)), size, nil, 0, &ret, nil, 0)
-       return os.NewSyscallError("WSAIoctl", err)
+       return os.NewSyscallError("wsaioctl", err)
 }