Skip to content

Commit 055ecb7

Browse files
committed
net: fix inconsistent errors
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 <[email protected]>
1 parent 2708f19 commit 055ecb7

27 files changed

+225
-138
lines changed

src/net/fd_plan9.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ func (fd *netFD) file(f *os.File, s string) (*os.File, error) {
202202
dfd, err := syscall.Dup(int(f.Fd()), -1)
203203
syscall.ForkLock.RUnlock()
204204
if err != nil {
205-
return nil, err
205+
return nil, os.NewSyscallError("dup", err)
206206
}
207207
return os.NewFile(uintptr(dfd), s), nil
208208
}

src/net/fd_unix.go

+36-11
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
9393
}
9494
fallthrough
9595
default:
96-
return err
96+
return os.NewSyscallError("connect", err)
9797
}
9898
if err := fd.init(); err != nil {
9999
return err
@@ -116,14 +116,14 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
116116
}
117117
nerr, err := getsockoptIntFunc(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
118118
if err != nil {
119-
return err
119+
return os.NewSyscallError("getsockopt", err)
120120
}
121121
switch err := syscall.Errno(nerr); err {
122122
case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
123123
case syscall.Errno(0), syscall.EISCONN:
124124
return nil
125125
default:
126-
return err
126+
return os.NewSyscallError("getsockopt", err)
127127
}
128128
}
129129
}
@@ -205,7 +205,7 @@ func (fd *netFD) shutdown(how int) error {
205205
return err
206206
}
207207
defer fd.decref()
208-
return syscall.Shutdown(fd.sysfd, how)
208+
return os.NewSyscallError("shutdown", syscall.Shutdown(fd.sysfd, how))
209209
}
210210

211211
func (fd *netFD) closeRead() error {
@@ -237,6 +237,9 @@ func (fd *netFD) Read(p []byte) (n int, err error) {
237237
err = fd.eofError(n, err)
238238
break
239239
}
240+
if _, ok := err.(syscall.Errno); ok {
241+
err = os.NewSyscallError("read", err)
242+
}
240243
return
241244
}
242245

@@ -261,6 +264,9 @@ func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
261264
err = fd.eofError(n, err)
262265
break
263266
}
267+
if _, ok := err.(syscall.Errno); ok {
268+
err = os.NewSyscallError("recvfrom", err)
269+
}
264270
return
265271
}
266272

@@ -285,6 +291,9 @@ func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.S
285291
err = fd.eofError(n, err)
286292
break
287293
}
294+
if _, ok := err.(syscall.Errno); ok {
295+
err = os.NewSyscallError("recvmsg", err)
296+
}
288297
return
289298
}
290299

@@ -318,6 +327,9 @@ func (fd *netFD) Write(p []byte) (nn int, err error) {
318327
break
319328
}
320329
}
330+
if _, ok := err.(syscall.Errno); ok {
331+
err = os.NewSyscallError("write", err)
332+
}
321333
return nn, err
322334
}
323335

@@ -341,6 +353,9 @@ func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
341353
if err == nil {
342354
n = len(p)
343355
}
356+
if _, ok := err.(syscall.Errno); ok {
357+
err = os.NewSyscallError("sendto", err)
358+
}
344359
return
345360
}
346361

@@ -364,6 +379,9 @@ func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob
364379
if err == nil {
365380
oobn = len(oob)
366381
}
382+
if _, ok := err.(syscall.Errno); ok {
383+
err = os.NewSyscallError("sendmsg", err)
384+
}
367385
return
368386
}
369387

@@ -381,13 +399,20 @@ func (fd *netFD) accept() (netfd *netFD, err error) {
381399
for {
382400
s, rsa, err = accept(fd.sysfd)
383401
if err != nil {
384-
if err == syscall.EAGAIN {
402+
nerr, ok := err.(*os.SyscallError)
403+
if !ok {
404+
return nil, err
405+
}
406+
switch nerr.Err {
407+
case syscall.EAGAIN:
385408
if err = fd.pd.WaitRead(); err == nil {
386409
continue
387410
}
388-
} else if err == syscall.ECONNABORTED {
389-
// This means that a socket on the listen queue was closed
390-
// before we Accept()ed it; it's a silly error, so try again.
411+
case syscall.ECONNABORTED:
412+
// This means that a socket on the
413+
// listen queue was closed before we
414+
// Accept()ed it; it's a silly error,
415+
// so try again.
391416
continue
392417
}
393418
return nil, err
@@ -436,7 +461,7 @@ func dupCloseOnExec(fd int) (newfd int, err error) {
436461
// from now on.
437462
atomic.StoreInt32(&tryDupCloexec, 0)
438463
default:
439-
return -1, e1
464+
return -1, os.NewSyscallError("fcntl", e1)
440465
}
441466
}
442467
return dupCloseOnExecOld(fd)
@@ -449,7 +474,7 @@ func dupCloseOnExecOld(fd int) (newfd int, err error) {
449474
defer syscall.ForkLock.RUnlock()
450475
newfd, err = syscall.Dup(fd)
451476
if err != nil {
452-
return -1, err
477+
return -1, os.NewSyscallError("dup", err)
453478
}
454479
syscall.CloseOnExec(newfd)
455480
return
@@ -466,7 +491,7 @@ func (fd *netFD) dup() (f *os.File, err error) {
466491
// I/O will block the thread instead of letting us use the epoll server.
467492
// Everything will still work, just with more threads.
468493
if err = syscall.SetNonblock(ns, false); err != nil {
469-
return nil, err
494+
return nil, os.NewSyscallError("setnonblock", err)
470495
}
471496

472497
return os.NewFile(uintptr(ns), fd.name()), nil

src/net/fd_windows.go

+32-9
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func sysInit() {
3838
var d syscall.WSAData
3939
e := syscall.WSAStartup(uint32(0x202), &d)
4040
if e != nil {
41-
initErr = os.NewSyscallError("WSAStartup", e)
41+
initErr = os.NewSyscallError("wsastartup", e)
4242
}
4343
canCancelIO = syscall.LoadCancelIoEx() == nil
4444
if syscall.LoadGetAddrInfo() == nil {
@@ -297,7 +297,7 @@ func (fd *netFD) init() error {
297297
size := uint32(unsafe.Sizeof(flag))
298298
err := syscall.WSAIoctl(fd.sysfd, syscall.SIO_UDP_CONNRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0)
299299
if err != nil {
300-
return os.NewSyscallError("WSAIoctl", err)
300+
return os.NewSyscallError("wsaioctl", err)
301301
}
302302
}
303303
fd.rop.mode = 'r'
@@ -331,7 +331,7 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
331331
defer fd.setWriteDeadline(noDeadline)
332332
}
333333
if !canUseConnectEx(fd.net) {
334-
return connectFunc(fd.sysfd, ra)
334+
return os.NewSyscallError("connect", connectFunc(fd.sysfd, ra))
335335
}
336336
// ConnectEx windows API requires an unconnected, previously bound socket.
337337
if la == nil {
@@ -344,7 +344,7 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
344344
panic("unexpected type in connect")
345345
}
346346
if err := syscall.Bind(fd.sysfd, la); err != nil {
347-
return err
347+
return os.NewSyscallError("bind", err)
348348
}
349349
}
350350
// Call ConnectEx API.
@@ -354,10 +354,13 @@ func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
354354
return connectExFunc(o.fd.sysfd, o.sa, nil, 0, nil, &o.o)
355355
})
356356
if err != nil {
357+
if _, ok := err.(syscall.Errno); ok {
358+
err = os.NewSyscallError("connectex", err)
359+
}
357360
return err
358361
}
359362
// Refresh socket properties.
360-
return syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
363+
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))))
361364
}
362365

363366
func (fd *netFD) destroy() {
@@ -461,7 +464,11 @@ func (fd *netFD) Read(buf []byte) (int, error) {
461464
if raceenabled {
462465
raceAcquire(unsafe.Pointer(&ioSync))
463466
}
464-
return n, fd.eofError(n, err)
467+
err = fd.eofError(n, err)
468+
if _, ok := err.(syscall.Errno); ok {
469+
err = os.NewSyscallError("wsarecv", err)
470+
}
471+
return n, err
465472
}
466473

467474
func (fd *netFD) readFrom(buf []byte) (int, syscall.Sockaddr, error) {
@@ -482,11 +489,14 @@ func (fd *netFD) readFrom(buf []byte) (int, syscall.Sockaddr, error) {
482489
return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
483490
})
484491
err = fd.eofError(n, err)
492+
if _, ok := err.(syscall.Errno); ok {
493+
err = os.NewSyscallError("wsarecvfrom", err)
494+
}
485495
if err != nil {
486496
return n, nil, err
487497
}
488498
sa, _ := o.rsa.Sockaddr()
489-
return n, sa, err
499+
return n, sa, nil
490500
}
491501

492502
func (fd *netFD) Write(buf []byte) (int, error) {
@@ -502,6 +512,9 @@ func (fd *netFD) Write(buf []byte) (int, error) {
502512
n, err := wsrv.ExecIO(o, "WSASend", func(o *operation) error {
503513
return syscall.WSASend(o.fd.sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil)
504514
})
515+
if _, ok := err.(syscall.Errno); ok {
516+
err = os.NewSyscallError("wsasend", err)
517+
}
505518
return n, err
506519
}
507520

@@ -519,6 +532,9 @@ func (fd *netFD) writeTo(buf []byte, sa syscall.Sockaddr) (int, error) {
519532
n, err := wsrv.ExecIO(o, "WSASendto", func(o *operation) error {
520533
return syscall.WSASendto(o.fd.sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
521534
})
535+
if _, ok := err.(syscall.Errno); ok {
536+
err = os.NewSyscallError("wsasendto", err)
537+
}
522538
return n, err
523539
}
524540

@@ -548,14 +564,17 @@ func (fd *netFD) acceptOne(rawsa []syscall.RawSockaddrAny, o *operation) (*netFD
548564
})
549565
if err != nil {
550566
netfd.Close()
567+
if _, ok := err.(syscall.Errno); ok {
568+
err = os.NewSyscallError("acceptex", err)
569+
}
551570
return nil, err
552571
}
553572

554573
// Inherit properties of the listening socket.
555574
err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
556575
if err != nil {
557576
netfd.Close()
558-
return nil, err
577+
return nil, os.NewSyscallError("setsockopt", err)
559578
}
560579

561580
return netfd, nil
@@ -581,7 +600,11 @@ func (fd *netFD) accept() (*netFD, error) {
581600
// before AcceptEx could complete. These errors relate to new
582601
// connection, not to AcceptEx, so ignore broken connection and
583602
// try AcceptEx again for more connections.
584-
errno, ok := err.(syscall.Errno)
603+
nerr, ok := err.(*os.SyscallError)
604+
if !ok {
605+
return nil, err
606+
}
607+
errno, ok := nerr.Err.(syscall.Errno)
585608
if !ok {
586609
return nil, err
587610
}

src/net/file_plan9.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func newFileFD(f *os.File) (net *netFD, err error) {
3939

4040
path, err := syscall.Fd2path(int(f.Fd()))
4141
if err != nil {
42-
return nil, err
42+
return nil, os.NewSyscallError("fd2path", err)
4343
}
4444
comp := splitAtBytes(path, "/")
4545
n := len(comp)
@@ -54,7 +54,7 @@ func newFileFD(f *os.File) (net *netFD, err error) {
5454
fd, err := syscall.Dup(int(f.Fd()), -1)
5555
syscall.ForkLock.RUnlock()
5656
if err != nil {
57-
return nil, err
57+
return nil, os.NewSyscallError("dup", err)
5858
}
5959
defer close(fd)
6060

src/net/file_unix.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ func newFileFD(f *os.File) (*netFD, error) {
1919

2020
if err = syscall.SetNonblock(fd, true); err != nil {
2121
closeFunc(fd)
22-
return nil, err
22+
return nil, os.NewSyscallError("setnonblock", err)
2323
}
2424

2525
sotype, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE)
2626
if err != nil {
2727
closeFunc(fd)
28-
return nil, err
28+
return nil, os.NewSyscallError("getsockopt", err)
2929
}
3030

3131
family := syscall.AF_UNSPEC

src/net/interface_bsd.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package net
88

99
import (
10+
"os"
1011
"syscall"
1112
"unsafe"
1213
)
@@ -17,11 +18,11 @@ import (
1718
func interfaceTable(ifindex int) ([]Interface, error) {
1819
tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, ifindex)
1920
if err != nil {
20-
return nil, err
21+
return nil, os.NewSyscallError("routerib", err)
2122
}
2223
msgs, err := syscall.ParseRoutingMessage(tab)
2324
if err != nil {
24-
return nil, err
25+
return nil, os.NewSyscallError("parseroutingmessage", err)
2526
}
2627
return parseInterfaceTable(ifindex, msgs)
2728
}
@@ -50,7 +51,7 @@ loop:
5051
func newLink(m *syscall.InterfaceMessage) (*Interface, error) {
5152
sas, err := syscall.ParseRoutingSockaddr(m)
5253
if err != nil {
53-
return nil, err
54+
return nil, os.NewSyscallError("parseroutingsockaddr", err)
5455
}
5556
ifi := &Interface{Index: int(m.Header.Index), Flags: linkFlags(m.Header.Flags)}
5657
sa, _ := sas[syscall.RTAX_IFP].(*syscall.SockaddrDatalink)
@@ -103,11 +104,11 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
103104
}
104105
tab, err := syscall.RouteRIB(syscall.NET_RT_IFLIST, index)
105106
if err != nil {
106-
return nil, err
107+
return nil, os.NewSyscallError("routerib", err)
107108
}
108109
msgs, err := syscall.ParseRoutingMessage(tab)
109110
if err != nil {
110-
return nil, err
111+
return nil, os.NewSyscallError("parseroutingmessage", err)
111112
}
112113
var ift []Interface
113114
if index == 0 {
@@ -144,7 +145,7 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
144145
func newAddr(ifi *Interface, m *syscall.InterfaceAddrMessage) (*IPNet, error) {
145146
sas, err := syscall.ParseRoutingSockaddr(m)
146147
if err != nil {
147-
return nil, err
148+
return nil, os.NewSyscallError("parseroutingsockaddr", err)
148149
}
149150
ifa := &IPNet{}
150151
switch sa := sas[syscall.RTAX_NETMASK].(type) {

0 commit comments

Comments
 (0)