]> Cypherpunks repositories - gostls13.git/commitdiff
net: make WriteTo, WriteToUnix and WriteMsgUnix fail when connectionless-mode UnixCon...
authorMikio Hara <mikioh.mikioh@gmail.com>
Wed, 2 Apr 2014 10:42:05 +0000 (19:42 +0900)
committerMikio Hara <mikioh.mikioh@gmail.com>
Wed, 2 Apr 2014 10:42:05 +0000 (19:42 +0900)
This CL tries to fill the gap between Linux and other Unix-like systems
in the same way UDPConn already did.

Fixes #7677.

LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/83330045

src/pkg/net/unix_test.go
src/pkg/net/unixsock_posix.go

index 91df3ff88769bc53454a9d4c7765a5aa349cbf5c..24b6bf9da7208bd8e81123ba9e1a421c7ddab0bb 100644 (file)
@@ -151,6 +151,73 @@ func TestUnixAutobindClose(t *testing.T) {
        ln.Close()
 }
 
+func TestUnixgramWrite(t *testing.T) {
+       addr := testUnixAddr()
+       laddr, err := ResolveUnixAddr("unixgram", addr)
+       if err != nil {
+               t.Fatalf("ResolveUnixAddr failed: %v", err)
+       }
+       c, err := ListenPacket("unixgram", addr)
+       if err != nil {
+               t.Fatalf("ListenPacket failed: %v", err)
+       }
+       defer os.Remove(addr)
+       defer c.Close()
+
+       testUnixgramWriteConn(t, laddr)
+       testUnixgramWritePacketConn(t, laddr)
+}
+
+func testUnixgramWriteConn(t *testing.T, raddr *UnixAddr) {
+       c, err := Dial("unixgram", raddr.String())
+       if err != nil {
+               t.Fatalf("Dial failed: %v", err)
+       }
+       defer c.Close()
+
+       if _, err := c.(*UnixConn).WriteToUnix([]byte("Connection-oriented mode socket"), raddr); err == nil {
+               t.Fatal("WriteToUnix should fail")
+       } else if err.(*OpError).Err != ErrWriteToConnected {
+               t.Fatalf("WriteToUnix should fail as ErrWriteToConnected: %v", err)
+       }
+       if _, err = c.(*UnixConn).WriteTo([]byte("Connection-oriented mode socket"), raddr); err == nil {
+               t.Fatal("WriteTo should fail")
+       } else if err.(*OpError).Err != ErrWriteToConnected {
+               t.Fatalf("WriteTo should fail as ErrWriteToConnected: %v", err)
+       }
+       if _, _, err = c.(*UnixConn).WriteMsgUnix([]byte("Connection-oriented mode socket"), nil, raddr); err == nil {
+               t.Fatal("WriteTo should fail")
+       } else if err.(*OpError).Err != ErrWriteToConnected {
+               t.Fatalf("WriteMsgUnix should fail as ErrWriteToConnected: %v", err)
+       }
+       if _, err := c.Write([]byte("Connection-oriented mode socket")); err != nil {
+               t.Fatalf("Write failed: %v", err)
+       }
+}
+
+func testUnixgramWritePacketConn(t *testing.T, raddr *UnixAddr) {
+       addr := testUnixAddr()
+       c, err := ListenPacket("unixgram", addr)
+       if err != nil {
+               t.Fatalf("ListenPacket failed: %v", err)
+       }
+       defer os.Remove(addr)
+       defer c.Close()
+
+       if _, err := c.(*UnixConn).WriteToUnix([]byte("Connectionless mode socket"), raddr); err != nil {
+               t.Fatalf("WriteToUnix failed: %v", err)
+       }
+       if _, err := c.WriteTo([]byte("Connectionless mode socket"), raddr); err != nil {
+               t.Fatalf("WriteTo failed: %v", err)
+       }
+       if _, _, err := c.(*UnixConn).WriteMsgUnix([]byte("Connectionless mode socket"), nil, raddr); err != nil {
+               t.Fatalf("WriteMsgUnix failed: %v", err)
+       }
+       if _, err := c.(*UnixConn).Write([]byte("Connectionless mode socket")); err == nil {
+               t.Fatal("Write should fail")
+       }
+}
+
 func TestUnixConnLocalAndRemoteNames(t *testing.T) {
        for _, laddr := range []string{"", testUnixAddr()} {
                laddr := laddr
index 83f7c3f979851787d0d0d8f095653a1415da5e48..a5f8d0c7621c785147d1049d045258474a64cb76 100644 (file)
@@ -171,6 +171,9 @@ func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (n int, err error) {
        if !c.ok() {
                return 0, syscall.EINVAL
        }
+       if c.fd.isConnected {
+               return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+       }
        if addr == nil {
                return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
        }
@@ -200,6 +203,9 @@ func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err
        if !c.ok() {
                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}
+       }
        if addr != nil {
                if addr.Net != sotypeToNet(c.fd.sotype) {
                        return 0, 0, syscall.EAFNOSUPPORT