diff options
author | Andrew Gerrand <adg@golang.org> | 2013-11-01 10:58:25 +1100 |
---|---|---|
committer | Andrew Gerrand <adg@golang.org> | 2013-11-01 10:58:25 +1100 |
commit | 287fa600ed86c052f356eba4d2f5e537a45ca370 (patch) | |
tree | 7bb62e3df0d1114ad51b05f89768e9f37a5efa88 | |
parent | 000c1c5127034e0d3af897c43e79f7ce952ea184 (diff) | |
download | go-287fa600ed86c052f356eba4d2f5e537a45ca370.tar.gz go-287fa600ed86c052f356eba4d2f5e537a45ca370.zip |
[release-branch.go1.2] net: make sure failed Dial returns nil Conn
««« CL 14950045 / 1e60ffd5933d
net: make sure failed Dial returns nil Conn
Fixes #6614.
R=golang-dev, bradfitz, mikioh.mikioh
CC=golang-dev
https://golang.org/cl/14950045
»»»
R=golang-dev
CC=golang-dev
https://golang.org/cl/20170047
-rw-r--r-- | src/pkg/net/dial.go | 34 | ||||
-rw-r--r-- | src/pkg/net/net_test.go | 38 |
2 files changed, 62 insertions, 10 deletions
diff --git a/src/pkg/net/dial.go b/src/pkg/net/dial.go index fb47795d79..6304818bf1 100644 --- a/src/pkg/net/dial.go +++ b/src/pkg/net/dial.go @@ -215,26 +215,30 @@ func dialMulti(net, addr string, la Addr, ras addrList, deadline time.Time) (Con // dialSingle attempts to establish and returns a single connection to // the destination address. -func dialSingle(net, addr string, la, ra Addr, deadline time.Time) (Conn, error) { +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())} } switch ra := ra.(type) { case *TCPAddr: la, _ := la.(*TCPAddr) - return dialTCP(net, la, ra, deadline) + c, err = dialTCP(net, la, ra, deadline) case *UDPAddr: la, _ := la.(*UDPAddr) - return dialUDP(net, la, ra, deadline) + c, err = dialUDP(net, la, ra, deadline) case *IPAddr: la, _ := la.(*IPAddr) - return dialIP(net, la, ra, deadline) + c, err = dialIP(net, la, ra, deadline) case *UnixAddr: la, _ := la.(*UnixAddr) - return dialUnix(net, la, ra, deadline) + 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}} } + if err != nil { + return nil, err // c is non-nil interface containing nil pointer + } + return c, nil } // Listen announces on the local network address laddr. @@ -246,14 +250,19 @@ func Listen(net, laddr string) (Listener, error) { if err != nil { return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err} } + var l Listener switch la := la.toAddr().(type) { case *TCPAddr: - return ListenTCP(net, la) + l, err = ListenTCP(net, la) case *UnixAddr: - return ListenUnix(net, la) + l, err = ListenUnix(net, la) default: return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}} } + if err != nil { + return nil, err // l is non-nil interface containing nil pointer + } + return l, nil } // ListenPacket announces on the local network address laddr. @@ -265,14 +274,19 @@ func ListenPacket(net, laddr string) (PacketConn, error) { if err != nil { return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err} } + var l PacketConn switch la := la.toAddr().(type) { case *UDPAddr: - return ListenUDP(net, la) + l, err = ListenUDP(net, la) case *IPAddr: - return ListenIP(net, la) + l, err = ListenIP(net, la) case *UnixAddr: - return ListenUnixgram(net, la) + l, err = ListenUnixgram(net, la) default: return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}} } + if err != nil { + return nil, err // l is non-nil interface containing nil pointer + } + return l, nil } diff --git a/src/pkg/net/net_test.go b/src/pkg/net/net_test.go index ee6cf0fcdd..1320096df8 100644 --- a/src/pkg/net/net_test.go +++ b/src/pkg/net/net_test.go @@ -218,3 +218,41 @@ func TestTCPClose(t *testing.T) { t.Fatal(err) } } + +func TestErrorNil(t *testing.T) { + c, err := Dial("tcp", "127.0.0.1:65535") + if err == nil { + t.Fatal("Dial 127.0.0.1:65535 succeeded") + } + if c != nil { + t.Fatalf("Dial returned non-nil interface %T(%v) with err != nil", c, c) + } + + // Make Listen fail by relistening on the same address. + l, err := Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatal("Listen 127.0.0.1:0: %v", err) + } + defer l.Close() + l1, err := Listen("tcp", l.Addr().String()) + if err == nil { + t.Fatal("second Listen %v: %v", l.Addr(), err) + } + if l1 != nil { + t.Fatalf("Listen returned non-nil interface %T(%v) with err != nil", l1, l1) + } + + // Make ListenPacket fail by relistening on the same address. + lp, err := ListenPacket("udp", "127.0.0.1:0") + if err != nil { + t.Fatal("Listen 127.0.0.1:0: %v", err) + } + defer lp.Close() + lp1, err := ListenPacket("udp", lp.LocalAddr().String()) + if err == nil { + t.Fatal("second Listen %v: %v", lp.LocalAddr(), err) + } + if lp1 != nil { + t.Fatalf("ListenPacket returned non-nil interface %T(%v) with err != nil", lp1, lp1) + } +} |