net: add FileConn, FilePacketConn, FileListener
R=iant, rsc, brainman
CC=golang-dev
https://golang.org/cl/4306042
diff --git a/src/pkg/net/file_test.go b/src/pkg/net/file_test.go
new file mode 100644
index 0000000..1824d04
--- /dev/null
+++ b/src/pkg/net/file_test.go
@@ -0,0 +1,131 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+ "os"
+ "reflect"
+ "runtime"
+ "syscall"
+ "testing"
+)
+
+type listenerFile interface {
+ Listener
+ File() (f *os.File, err os.Error)
+}
+
+type packetConnFile interface {
+ PacketConn
+ File() (f *os.File, err os.Error)
+}
+
+type connFile interface {
+ Conn
+ File() (f *os.File, err os.Error)
+}
+
+func testFileListener(t *testing.T, net, laddr string) {
+ if net == "tcp" {
+ laddr += ":0" // any available port
+ }
+ l, err := Listen(net, laddr)
+ if err != nil {
+ t.Fatalf("Listen failed: %v", err)
+ }
+ defer l.Close()
+ lf := l.(listenerFile)
+ f, err := lf.File()
+ if err != nil {
+ t.Fatalf("File failed: %v", err)
+ }
+ c, err := FileListener(f)
+ if err != nil {
+ t.Fatalf("FileListener failed: %v", err)
+ }
+ if !reflect.DeepEqual(l.Addr(), c.Addr()) {
+ t.Fatalf("Addrs not equal: %#v != %#v", l.Addr(), c.Addr())
+ }
+ if err := c.Close(); err != nil {
+ t.Fatalf("Close failed: %v", err)
+ }
+ if err := f.Close(); err != nil {
+ t.Fatalf("Close failed: %v", err)
+ }
+}
+
+func TestFileListener(t *testing.T) {
+ if runtime.GOOS == "windows" {
+ return
+ }
+ testFileListener(t, "tcp", "127.0.0.1")
+ testFileListener(t, "tcp", "127.0.0.1")
+ if kernelSupportsIPv6() {
+ testFileListener(t, "tcp", "[::ffff:127.0.0.1]")
+ testFileListener(t, "tcp", "127.0.0.1")
+ testFileListener(t, "tcp", "[::ffff:127.0.0.1]")
+ }
+ if syscall.OS == "linux" {
+ testFileListener(t, "unix", "@gotest/net")
+ testFileListener(t, "unixpacket", "@gotest/net")
+ }
+}
+
+func testFilePacketConn(t *testing.T, pcf packetConnFile) {
+ f, err := pcf.File()
+ if err != nil {
+ t.Fatalf("File failed: %v", err)
+ }
+ c, err := FilePacketConn(f)
+ if err != nil {
+ t.Fatalf("FilePacketConn failed: %v", err)
+ }
+ if !reflect.DeepEqual(pcf.LocalAddr(), c.LocalAddr()) {
+ t.Fatalf("LocalAddrs not equal: %#v != %#v", pcf.LocalAddr(), c.LocalAddr())
+ }
+ if err := c.Close(); err != nil {
+ t.Fatalf("Close failed: %v", err)
+ }
+ if err := f.Close(); err != nil {
+ t.Fatalf("Close failed: %v", err)
+ }
+}
+
+func testFilePacketConnListen(t *testing.T, net, laddr string) {
+ l, err := ListenPacket(net, laddr)
+ if err != nil {
+ t.Fatalf("Listen failed: %v", err)
+ }
+ testFilePacketConn(t, l.(packetConnFile))
+ if err := l.Close(); err != nil {
+ t.Fatalf("Close failed: %v", err)
+ }
+}
+
+func testFilePacketConnDial(t *testing.T, net, raddr string) {
+ c, err := Dial(net, "", raddr)
+ if err != nil {
+ t.Fatalf("Dial failed: %v", err)
+ }
+ testFilePacketConn(t, c.(packetConnFile))
+ if err := c.Close(); err != nil {
+ t.Fatalf("Close failed: %v", err)
+ }
+}
+
+func TestFilePacketConn(t *testing.T) {
+ if runtime.GOOS == "windows" {
+ return
+ }
+ testFilePacketConnListen(t, "udp", "127.0.0.1:0")
+ testFilePacketConnDial(t, "udp", "127.0.0.1:12345")
+ if kernelSupportsIPv6() {
+ testFilePacketConnListen(t, "udp", "[::1]:0")
+ testFilePacketConnDial(t, "udp", "[::ffff:127.0.0.1]:12345")
+ }
+ if syscall.OS == "linux" {
+ testFilePacketConnListen(t, "unixgram", "@gotest1/net")
+ }
+}