aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Gerrand <adg@golang.org>2013-11-01 10:58:25 +1100
committerAndrew Gerrand <adg@golang.org>2013-11-01 10:58:25 +1100
commit287fa600ed86c052f356eba4d2f5e537a45ca370 (patch)
tree7bb62e3df0d1114ad51b05f89768e9f37a5efa88
parent000c1c5127034e0d3af897c43e79f7ce952ea184 (diff)
downloadgo-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.go34
-rw-r--r--src/pkg/net/net_test.go38
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)
+ }
+}