split ipsock.go, sock.go, and unixsock.go out of net.go
prior to cleanup.  no changes, only moving.

remove dependencies on strconv and strings

R=r
http://go/go-review/1017010
diff --git a/src/pkg/net/net.go b/src/pkg/net/net.go
index 5fb49d4..8669ed3 100644
--- a/src/pkg/net/net.go
+++ b/src/pkg/net/net.go
@@ -4,52 +4,11 @@
 
 package net
 
-import (
-	"os";
-	"reflect";
-	"strconv";
-	"strings";
-	"syscall";
-)
+// TODO(rsc):
+//	support for raw IP sockets
+//	support for raw ethernet sockets
 
-var errMissingAddress = os.ErrorString("missing address")
-
-type OpError struct {
-	Op string;
-	Net string;
-	Addr string;
-	Error os.Error;
-}
-
-func (e *OpError) String() string {
-	s := e.Op;
-	if e.Net != "" {
-		s += " " + e.Net;
-	}
-	if e.Addr != "" {
-		s += " " + e.Addr;
-	}
-	s += ": " + e.Error.String();
-	return s;
-}
-
-type AddrError struct {
-	Error string;
-	Addr string;
-}
-
-func (e *AddrError) String() string {
-	s := e.Error;
-	if e.Addr != "" {
-		s += " " + e.Addr;
-	}
-	return s;
-}
-
-type UnknownNetworkError string
-func (e UnknownNetworkError) String() string {
-	return "unknown network " + string(e);
-}
+import "os"
 
 // Conn is a generic network connection.
 type Conn interface {
@@ -134,681 +93,12 @@
 	BindToDevice(dev string) os.Error;
 }
 
-// Should we try to use the IPv4 socket interface if we're
-// only dealing with IPv4 sockets?  As long as the host system
-// understands IPv6, it's okay to pass IPv4 addresses to the IPv6
-// interface.  That simplifies our code and is most general.
-// Unfortunately, we need to run on kernels built without IPv6 support too.
-// So probe the kernel to figure it out.
-func kernelSupportsIPv6() bool {
-	fd, e := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP);
-	if fd >= 0 {
-		syscall.Close(fd)
-	}
-	return e == 0
-}
-
-var preferIPv4 = !kernelSupportsIPv6()
-
-// TODO(rsc): if syscall.OS == "linux", we're supposd to read
-// /proc/sys/net/core/somaxconn,
-// to take advantage of kernels that have raised the limit.
-func listenBacklog() int {
-	return syscall.SOMAXCONN
-}
-
-// Split "host:port" into "host" and "port".
-// Host cannot contain colons unless it is bracketed.
-func splitHostPort(hostport string) (host, port string, err os.Error) {
-	// The port starts after the last colon.
-	i := strings.LastIndex(hostport, ":");
-	if i < 0 {
-		err = &AddrError{"missing port in address", hostport};
-		return;
-	}
-
-	host, port = hostport[0:i], hostport[i+1:len(hostport)];
-
-	// Can put brackets around host ...
-	if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
-		host = host[1:len(host)-1]
-	} else {
-		// ... but if there are no brackets, no colons.
-		if byteIndex(host, ':') >= 0 {
-			err = &AddrError{"too many colons in address", hostport};
-			return;
-		}
-	}
-	return;
-}
-
-// Join "host" and "port" into "host:port".
-// If host contains colons, will join into "[host]:port".
-func joinHostPort(host, port string) string {
-	// If host has colons, have to bracket it.
-	if byteIndex(host, ':') >= 0 {
-		return "[" + host + "]:" + port
-	}
-	return host + ":" + port
-}
-
-// Convert "host:port" into IP address and port.
-// For now, host and port must be numeric literals.
-// Eventually, we'll have name resolution.
-func hostPortToIP(net, hostport, mode string) (ip IP, iport int, err os.Error) {
-	host, port, err := splitHostPort(hostport);
-	if err != nil {
-		goto Error;
-	}
-
-	var addr IP;
-	if host == "" {
-		if mode != "listen" {
-			err = &AddrError{"no host in address", hostport};
-			goto Error;
-		}
-		if preferIPv4 {
-			addr = IPv4zero;
-		} else {
-			addr = IPzero;	// wildcard - listen to all
-		}
-	}
-
-	// Try as an IP address.
-	if addr == nil {
-		addr = ParseIP(host);
-	}
-	if addr == nil {
-		// Not an IP address.  Try as a DNS name.
-		_, addrs, err1 := LookupHost(host);
-		if err1 != nil {
-			err = err1;
-			goto Error;
-		}
-		addr = ParseIP(addrs[0]);
-		if addr == nil {
-			// should not happen
-			err = &AddrError{"LookupHost returned invalid address", addrs[0]};
-			goto Error;
-		}
-	}
-
-	p, i, ok := dtoi(port, 0);
-	if !ok || i != len(port) {
-		p, err = LookupPort(net, port);
-		if err != nil {
-			goto Error;
-		}
-	}
-	if p < 0 || p > 0xFFFF {
-		err = &AddrError{"invalid port", port};
-		goto Error;
-	}
-
-	return addr, p, nil;
-
-Error:
-	return nil, 0, err;
-}
-
-type UnknownSocketError struct {
-	sa syscall.Sockaddr;
-}
-func (e *UnknownSocketError) String() string {
-	return "unknown socket address type " + reflect.Typeof(e.sa).String()
-}
-
-func sockaddrToString(sa syscall.Sockaddr) (name string, err os.Error) {
-	switch a := sa.(type) {
-	case *syscall.SockaddrInet4:
-		return joinHostPort(IP(&a.Addr).String(), strconv.Itoa(a.Port)), nil;
-	case *syscall.SockaddrInet6:
-		return joinHostPort(IP(&a.Addr).String(), strconv.Itoa(a.Port)), nil;
-	case *syscall.SockaddrUnix:
-		return a.Name, nil;
-	}
-
-	return "", &UnknownSocketError{sa};
-}
-
-func ipToSockaddr(family int, ip IP, port int) (syscall.Sockaddr, os.Error) {
-	switch family {
-	case syscall.AF_INET:
-		if ip = ip.To4(); ip == nil {
-			return nil, os.EINVAL
-		}
-		s := new(syscall.SockaddrInet4);
-		for i := 0; i < IPv4len; i++ {
-			s.Addr[i] = ip[i];
-		}
-		s.Port = port;
-		return s, nil;
-	case syscall.AF_INET6:
-		// IPv4 callers use 0.0.0.0 to mean "announce on any available address".
-		// In IPv6 mode, Linux treats that as meaning "announce on 0.0.0.0",
-		// which it refuses to do.  Rewrite to the IPv6 all zeros.
-		if p4 := ip.To4(); p4 != nil && p4[0] == 0 && p4[1] == 0 && p4[2] == 0 && p4[3] == 0 {
-			ip = IPzero;
-		}
-		if ip = ip.To16(); ip == nil {
-			return nil, os.EINVAL
-		}
-		s := new(syscall.SockaddrInet6);
-		for i := 0; i < IPv6len; i++ {
-			s.Addr[i] = ip[i];
-		}
-		s.Port = port;
-		return s, nil;
-	}
-	return nil, os.EINVAL;
-}
-
-// Boolean to int.
-func boolint(b bool) int {
-	if b {
-		return 1
-	}
-	return 0
-}
-
-// Generic socket creation.
-func socket(net, laddr, raddr string, f, p, t int, la, ra syscall.Sockaddr) (fd *netFD, err os.Error) {
-	// See ../syscall/exec.go for description of ForkLock.
-	syscall.ForkLock.RLock();
-	s, e := syscall.Socket(f, p, t);
-	if e != 0 {
-		syscall.ForkLock.RUnlock();
-		return nil, os.Errno(e)
-	}
-	syscall.CloseOnExec(s);
-	syscall.ForkLock.RUnlock();
-
-	// Allow reuse of recently-used addresses.
-	syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1);
-
-	if la != nil {
-		e = syscall.Bind(s, la);
-		if e != 0 {
-			syscall.Close(s);
-			return nil, os.Errno(e)
-		}
-	}
-
-	if ra != nil {
-		e = syscall.Connect(s, ra);
-		if e != 0 {
-			syscall.Close(s);
-			return nil, os.Errno(e)
-		}
-	}
-
-	fd, err = newFD(s, net, laddr, raddr);
-	if err != nil {
-		syscall.Close(s);
-		return nil, err
-	}
-
-	return fd, nil
-}
-
-
-// Generic implementation of Conn interface; not exported.
-type connBase struct {
-	fd *netFD;
-	raddr string;
-}
-
-func (c *connBase) LocalAddr() string {
-	if c == nil {
-		return ""
-	}
-	return c.fd.addr();
-}
-
-func (c *connBase) RemoteAddr() string {
-	if c == nil {
-		return ""
-	}
-	return c.fd.remoteAddr();
-}
-
-func (c *connBase) File() *os.File {
-	if c == nil {
-		return nil
-	}
-	return c.fd.file;
-}
-
-func (c *connBase) sysFD() int {
-	if c == nil || c.fd == nil {
-		return -1;
-	}
-	return c.fd.fd;
-}
-
-func (c *connBase) Read(b []byte) (n int, err os.Error) {
-	n, err = c.fd.Read(b);
-	return n, err
-}
-
-func (c *connBase) Write(b []byte) (n int, err os.Error) {
-	n, err = c.fd.Write(b);
-	return n, err
-}
-
-func (c *connBase) ReadFrom(b []byte) (n int, raddr string, err os.Error) {
-	if c == nil {
-		return -1, "", os.EINVAL
-	}
-	n, err = c.Read(b);
-	return n, c.raddr, err
-}
-
-func (c *connBase) WriteTo(raddr string, b []byte) (n int, err os.Error) {
-	if c == nil {
-		return -1, os.EINVAL
-	}
-	if raddr != c.raddr {
-		return -1, os.EINVAL
-	}
-	n, err = c.Write(b);
-	return n, err
-}
-
-func (c *connBase) Close() os.Error {
-	if c == nil {
-		return os.EINVAL
-	}
-	return c.fd.Close()
-}
-
-
-func setsockoptInt(fd, level, opt int, value int) os.Error {
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, level, opt, value));
-}
-
-func setsockoptNsec(fd, level, opt int, nsec int64) os.Error {
-	var tv = syscall.NsecToTimeval(nsec);
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptTimeval(fd, level, opt, &tv));
-}
-
-func (c *connBase) SetReadBuffer(bytes int) os.Error {
-	return setsockoptInt(c.sysFD(), syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes);
-}
-
-func (c *connBase) SetWriteBuffer(bytes int) os.Error {
-	return setsockoptInt(c.sysFD(), syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes);
-}
-
-func (c *connBase) SetReadTimeout(nsec int64) os.Error {
-	c.fd.rdeadline_delta = nsec;
-	return nil;
-}
-
-func (c *connBase) SetWriteTimeout(nsec int64) os.Error {
-	c.fd.wdeadline_delta = nsec;
-	return nil;
-}
-
-func (c *connBase) SetTimeout(nsec int64) os.Error {
-	if e := c.SetReadTimeout(nsec); e != nil {
-		return e
-	}
-	return c.SetWriteTimeout(nsec)
-}
-
-func (c *connBase) SetReuseAddr(reuse bool) os.Error {
-	return setsockoptInt(c.sysFD(), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, boolint(reuse));
-}
-
-func (c *connBase) BindToDevice(dev string) os.Error {
-	// TODO(rsc): call setsockopt with null-terminated string pointer
-	return os.EINVAL
-}
-
-func (c *connBase) SetDontRoute(dontroute bool) os.Error {
-	return setsockoptInt(c.sysFD(), syscall.SOL_SOCKET, syscall.SO_DONTROUTE, boolint(dontroute));
-}
-
-func (c *connBase) SetKeepAlive(keepalive bool) os.Error {
-	return setsockoptInt(c.sysFD(), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive));
-}
-
-func (c *connBase) SetLinger(sec int) os.Error {
-	var l syscall.Linger;
-	if sec >= 0 {
-		l.Onoff = 1;
-		l.Linger = int32(sec);
-	} else {
-		l.Onoff = 0;
-		l.Linger = 0;
-	}
-	e := syscall.SetsockoptLinger(c.sysFD(), syscall.SOL_SOCKET, syscall.SO_LINGER, &l);
-	return os.NewSyscallError("setsockopt", e);
-}
-
-
-// Internet sockets (TCP, UDP)
-
-func internetSocket(net, laddr, raddr string, proto int, mode string) (fd *netFD, err os.Error) {
-	// Parse addresses (unless they are empty).
-	var lip, rip IP;
-	var lport, rport int;
-
-	if laddr != "" {
-		if lip, lport, err = hostPortToIP(net, laddr, mode); err != nil {
-			goto Error;
-		}
-	}
-	if raddr != "" {
-		if rip, rport, err = hostPortToIP(net, raddr, mode); err != nil {
-			goto Error;
-		}
-	}
-
-	// Figure out IP version.
-	// If network has a suffix like "tcp4", obey it.
-	vers := 0;
-	switch net[len(net)-1] {
-	case '4':
-		vers = 4;
-	case '6':
-		vers = 6;
-	default:
-		// Otherwise, guess.
-		// If the addresses are IPv4 and we prefer IPv4, use 4; else 6.
-		if preferIPv4 && (lip == nil || lip.To4() != nil) && (rip == nil || rip.To4() != nil) {
-			vers = 4
-		} else {
-			vers = 6
-		}
-	}
-
-	var family int;
-	if vers == 4 {
-		family = syscall.AF_INET
-	} else {
-		family = syscall.AF_INET6
-	}
-
-	var la, ra syscall.Sockaddr;
-	if lip != nil {
-		if la, err = ipToSockaddr(family, lip, lport); err != nil {
-			goto Error;
-		}
-	}
-	if rip != nil {
-		if ra, err = ipToSockaddr(family, rip, rport); err != nil {
-			goto Error;
-		}
-	}
-
-	fd, err = socket(net, laddr, raddr, family, proto, 0, la, ra);
-	if err != nil {
-		goto Error;
-	}
-	return fd, nil;
-
-Error:
-	addr := raddr;
-	if mode == "listen" {
-		addr = laddr;
-	}
-	return nil, &OpError{mode, net, addr, err};
-}
-
-
-// TCP connections.
-
-// ConnTCP is an implementation of the Conn interface
-// for TCP network connections.
-type ConnTCP struct {
-	connBase
-}
-
-func (c *ConnTCP) SetNoDelay(nodelay bool) os.Error {
-	if c == nil {
-		return os.EINVAL
-	}
-	return setsockoptInt(c.sysFD(), syscall.IPPROTO_TCP, syscall.TCP_NODELAY, boolint(nodelay))
-}
-
-func newConnTCP(fd *netFD, raddr string) *ConnTCP {
-	c := new(ConnTCP);
-	c.fd = fd;
-	c.raddr = raddr;
-	c.SetNoDelay(true);
-	return c
-}
-
-// DialTCP is like Dial but can only connect to TCP networks
-// and returns a ConnTCP structure.
-func DialTCP(net, laddr, raddr string) (c *ConnTCP, err os.Error) {
-	if raddr == "" {
-		return nil, &OpError{"dial", "tcp", "", errMissingAddress}
-	}
-	fd, e := internetSocket(net, laddr, raddr, syscall.SOCK_STREAM, "dial");
-	if e != nil {
-		return nil, e
-	}
-	return newConnTCP(fd, raddr), nil
-}
-
-
-// UDP connections.
-
-// TODO(rsc): UDP headers mode
-
-// ConnUDP is an implementation of the Conn interface
-// for UDP network connections.
-type ConnUDP struct {
-	connBase
-}
-
-func newConnUDP(fd *netFD, raddr string) *ConnUDP {
-	c := new(ConnUDP);
-	c.fd = fd;
-	c.raddr = raddr;
-	return c
-}
-
-// DialUDP is like Dial but can only connect to UDP networks
-// and returns a ConnUDP structure.
-func DialUDP(net, laddr, raddr string) (c *ConnUDP, err os.Error) {
-	if raddr == "" {
-		return nil, &OpError{"dial", "udp", "", errMissingAddress}
-	}
-	fd, e := internetSocket(net, laddr, raddr, syscall.SOCK_DGRAM, "dial");
-	if e != nil {
-		return nil, e
-	}
-	return newConnUDP(fd, raddr), nil
-}
-
-
-// TODO: raw IP connections
-
-// TODO: raw ethernet connections
-
-
-// Unix domain sockets
-
-func unixSocket(net, laddr, raddr string, mode string) (fd *netFD, err os.Error) {
-	var proto int;
-	switch net {
-	default:
-		return nil, UnknownNetworkError(net);
-	case "unix":
-		proto = syscall.SOCK_STREAM;
-	case "unix-dgram":
-		proto = syscall.SOCK_DGRAM;
-	}
-
-	var la, ra syscall.Sockaddr;
-	switch mode {
-	default:
-		panic("unixSocket", mode);
-
-	case "dial":
-		if laddr != "" {
-			return nil, &OpError{mode, net, raddr, &AddrError{"unexpected local address", laddr}}
-		}
-		if raddr == "" {
-			return nil, &OpError{mode, net, "", errMissingAddress}
-		}
-		ra = &syscall.SockaddrUnix{Name: raddr};
-
-	case "listen":
-		if laddr == "" {
-			return nil, &OpError{mode, net, "", errMissingAddress}
-		}
-		la = &syscall.SockaddrUnix{Name: laddr};
-		if raddr != "" {
-			return nil, &OpError{mode, net, laddr, &AddrError{"unexpected remote address", raddr}}
-		}
-	}
-
-	fd, err = socket(net, laddr, raddr, syscall.AF_UNIX, proto, 0, la, ra);
-	if err != nil {
-		goto Error;
-	}
-	return fd, nil;
-
-Error:
-	addr := raddr;
-	if mode == "listen" {
-		addr = laddr;
-	}
-	return nil, &OpError{mode, net, addr, err};
-}
-
-// ConnUnix is an implementation of the Conn interface
-// for connections to Unix domain sockets.
-type ConnUnix struct {
-	connBase
-}
-
-func newConnUnix(fd *netFD, raddr string) *ConnUnix {
-	c := new(ConnUnix);
-	c.fd = fd;
-	c.raddr = raddr;
-	return c;
-}
-
-// DialUnix is like Dial but can only connect to Unix domain sockets
-// and returns a ConnUnix structure.  The laddr argument must be
-// the empty string; it is included only to match the signature of
-// the other dial routines.
-func DialUnix(net, laddr, raddr string) (c *ConnUnix, err os.Error) {
-	fd, e := unixSocket(net, laddr, raddr, "dial");
-	if e != nil {
-		return nil, e
-	}
-	return newConnUnix(fd, raddr), nil;
-}
-
-// ListenerUnix is a Unix domain socket listener.
-// Clients should typically use variables of type Listener
-// instead of assuming Unix domain sockets.
-type ListenerUnix struct {
-	fd *netFD;
-	laddr string
-}
-
-// ListenUnix announces on the Unix domain socket laddr and returns a Unix listener.
-// Net can be either "unix" (stream sockets) or "unix-dgram" (datagram sockets).
-func ListenUnix(net, laddr string) (l *ListenerUnix, err os.Error) {
-	fd, e := unixSocket(net, laddr, "", "listen");
-	if e != nil {
-		if pe, ok := e.(*os.PathError); ok {
-			e = pe.Error;
-		}
-		// Check for socket ``in use'' but ``refusing connections,''
-		// which means some program created it and exited
-		// without unlinking it from the file system.
-		// Clean up on that program's behalf and try again.
-		// Don't do this for Linux's ``abstract'' sockets, which begin with @.
-		if e != os.EADDRINUSE || laddr[0] == '@' {
-			return nil, e;
-		}
-		fd1, e1 := unixSocket(net, "", laddr, "dial");
-		if e1 == nil {
-			fd1.Close();
-		}
-		if pe, ok := e1.(*os.PathError); ok {
-			e1 = pe.Error;
-		}
-		if e1 != os.ECONNREFUSED {
-			return nil, e;
-		}
-		syscall.Unlink(laddr);
-		fd1, e1 = unixSocket(net, laddr, "", "listen");
-		if e1 != nil {
-			return nil, e;
-		}
-		fd = fd1;
-	}
-	e1 := syscall.Listen(fd.fd, 8); // listenBacklog());
-	if e1 != 0 {
-		syscall.Close(fd.fd);
-		return nil, &OpError{"listen", "unix", laddr, os.Errno(e1)};
-	}
-	return &ListenerUnix{fd, laddr}, nil;
-}
-
-// AcceptUnix accepts the next incoming call and returns the new connection
-// and the remote address.
-func (l *ListenerUnix) AcceptUnix() (c *ConnUnix, raddr string, err os.Error) {
-	if l == nil || l.fd == nil || l.fd.fd < 0 {
-		return nil, "", os.EINVAL
-	}
-	fd, e := l.fd.accept();
-	if e != nil {
-		return nil, "", e
-	}
-	return newConnUnix(fd, fd.raddr), raddr, nil
-}
-
-// Accept implements the Accept method in the Listener interface;
-// it waits for the next call and returns a generic Conn.
-func (l *ListenerUnix) Accept() (c Conn, raddr string, err os.Error) {
-	// TODO(rsc): Should return l.AcceptUnix() be okay here?
-	// There is a type conversion -- the first return arg of
-	// l.AcceptUnix() is *ConnUnix and it gets converted to Conn
-	// in the explicit assignment.
-	c, raddr, err = l.AcceptUnix();
-	return;
-}
-
-
-// Close stops listening on the Unix address.
-// Already accepted connections are not closed.
-func (l *ListenerUnix) Close() os.Error {
-	if l == nil || l.fd == nil {
-		return os.EINVAL
-	}
-
-	// The operating system doesn't clean up
-	// the file that announcing created, so
-	// we have to clean it up ourselves.
-	// There's a race here--we can't know for
-	// sure whether someone else has come along
-	// and replaced our socket name already--
-	// but this sequence (remove then close)
-	// is at least compatible with the auto-remove
-	// sequence in ListenUnix.  It's only non-Go
-	// programs that can mess us up.
-	if l.laddr[0] != '@' {
-		syscall.Unlink(l.laddr);
-	}
-	err := l.fd.Close();
-	l.fd = nil;
-	return err;
-}
-
-// Addr returns the listener's network address.
-func (l *ListenerUnix) Addr() string {
-	return l.fd.addr();
+// A Listener is a generic network listener.
+// Accept waits for the next connection and Close closes the connection.
+type Listener interface {
+	Accept() (c Conn, raddr string, err os.Error);
+	Close() os.Error;
+	Addr() string;	// Listener's network address
 }
 
 // Dial connects to the remote address raddr on the network net.
@@ -840,92 +130,10 @@
 	case "unix", "unix-dgram":
 		c, err := DialUnix(net, laddr, raddr);
 		return c, err;
-/*
-	case "ether":
-		c, err := DialEther(net, laddr, raddr);
-		return c, err;
-	case "ipv4":
-		c, err := DialIPv4(net, laddr, raddr);
-		return c, err;
-	case "ipv6":
-		c, err := DialIPv6(net, laddr, raddr);
-		return c, err
-*/
 	}
 	return nil, &OpError{"dial", net, raddr, UnknownNetworkError(net)};
 }
 
-// A Listener is a generic network listener.
-// Accept waits for the next connection and Close closes the connection.
-type Listener interface {
-	Accept() (c Conn, raddr string, err os.Error);
-	Close() os.Error;
-	Addr() string;	// Listener's network address
-}
-
-// ListenerTCP is a TCP network listener.
-// Clients should typically use variables of type Listener
-// instead of assuming TCP.
-type ListenerTCP struct {
-	fd *netFD;
-}
-
-// ListenTCP announces on the TCP address laddr and returns a TCP listener.
-// Net must be "tcp", "tcp4", or "tcp6".
-// If laddr has a port of 0, it means to listen on some available port.
-// The caller can use l.Addr() to retrieve the chosen address.
-func ListenTCP(net, laddr string) (l *ListenerTCP, err os.Error) {
-	fd, e := internetSocket(net, laddr, "", syscall.SOCK_STREAM, "listen");
-	if e != nil {
-		return nil, e
-	}
-	e1 := syscall.Listen(fd.fd, listenBacklog());
-	if e1 != 0 {
-		syscall.Close(fd.fd);
-		return nil, &OpError{"listen", "tcp", laddr, os.Errno(e1)};
-	}
-	l = new(ListenerTCP);
-	l.fd = fd;
-	return l, nil
-}
-
-// AcceptTCP accepts the next incoming call and returns the new connection
-// and the remote address.
-func (l *ListenerTCP) AcceptTCP() (c *ConnTCP, raddr string, err os.Error) {
-	if l == nil || l.fd == nil || l.fd.fd < 0 {
-		return nil, "", os.EINVAL
-	}
-	fd, e := l.fd.accept();
-	if e != nil {
-		return nil, "", e
-	}
-	return newConnTCP(fd, fd.raddr), fd.raddr, nil
-}
-
-// Accept implements the Accept method in the Listener interface;
-// it waits for the next call and returns a generic Conn.
-func (l *ListenerTCP) Accept() (c Conn, raddr string, err os.Error) {
-	c1, r1, e1 := l.AcceptTCP();
-	if e1 != nil {
-		return nil, "", e1
-	}
-	return c1, r1, nil
-}
-
-// Close stops listening on the TCP address.
-// Already Accepted connections are not closed.
-func (l *ListenerTCP) Close() os.Error {
-	if l == nil || l.fd == nil {
-		return os.EINVAL
-	}
-	return l.fd.Close()
-}
-
-// Addr returns the listener's network address.
-func (l *ListenerTCP) Addr() string {
-	return l.fd.addr();
-}
-
 // Listen announces on the local network address laddr.
 // The network string net must be "tcp", "tcp4", "tcp6",
 // "unix", or "unix-dgram".
@@ -943,11 +151,47 @@
 			return nil, err;
 		}
 		return l, nil;
-/*
-	more here
-*/
 	// BUG(rsc): Listen should support UDP.
 	}
 	return nil, UnknownNetworkError(net);
 }
 
+var errMissingAddress = os.ErrorString("missing address")
+
+type OpError struct {
+	Op string;
+	Net string;
+	Addr string;
+	Error os.Error;
+}
+
+func (e *OpError) String() string {
+	s := e.Op;
+	if e.Net != "" {
+		s += " " + e.Net;
+	}
+	if e.Addr != "" {
+		s += " " + e.Addr;
+	}
+	s += ": " + e.Error.String();
+	return s;
+}
+
+type AddrError struct {
+	Error string;
+	Addr string;
+}
+
+func (e *AddrError) String() string {
+	s := e.Error;
+	if e.Addr != "" {
+		s += " " + e.Addr;
+	}
+	return s;
+}
+
+type UnknownNetworkError string
+func (e UnknownNetworkError) String() string {
+	return "unknown network " + string(e);
+}
+