]> Cypherpunks repositories - gostls13.git/commitdiff
net: provide public access to file descriptors
authorKeith Rarick <kr@xph.us>
Fri, 5 Nov 2010 18:02:03 +0000 (14:02 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 5 Nov 2010 18:02:03 +0000 (14:02 -0400)
Fixes #918.

R=rsc, rog, brainman
CC=golang-dev
https://golang.org/cl/2904041

src/pkg/net/fd.go
src/pkg/net/fd_windows.go
src/pkg/net/tcpsock.go
src/pkg/net/udpsock.go
src/pkg/net/unixsock.go

index 7d3f227c1c7b9bec67924c6c5531adcef60d9232..d300e4bda532201987e74cdedb3c00ac85447070 100644 (file)
@@ -517,3 +517,17 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os.
        }
        return nfd, nil
 }
+
+func (fd *netFD) dup() (f *os.File, err os.Error) {
+       ns, e := syscall.Dup(fd.sysfd)
+       if e != 0 {
+               return nil, &OpError{"dup", fd.net, fd.laddr, os.Errno(e)}
+       }
+
+       // We want blocking mode for the new fd, hence the double negative.
+       if e = syscall.SetNonblock(ns, false); e != 0 {
+               return nil, &OpError{"setnonblock", fd.net, fd.laddr, os.Errno(e)}
+       }
+
+       return os.NewFile(ns, fd.sysfile.Name()), nil
+}
index c3ed9639d2b2b4af25e1694196fb57140d68fea7..1da2ca47ff1eaa9ec88f7cc6a31fd01bb7c31346 100644 (file)
@@ -373,3 +373,8 @@ func init() {
                initErr = os.NewSyscallError("WSAStartup", e)
        }
 }
+
+func (fd *netFD) dup() (f *os.File, err os.Error) {
+       // TODO: Implement this
+       return nil, os.NewSyscallError("dup", syscall.EWINDOWS)
+}
index eb846694ba8d9a137a79db571bd1ff71eca94619..b0cb8f99926411fef69872331e34f7776ceccbc9 100644 (file)
@@ -208,6 +208,11 @@ func (c *TCPConn) SetNoDelay(noDelay bool) os.Error {
        return setNoDelay(c.fd, noDelay)
 }
 
+// File returns a copy of the underlying os.File, set to blocking mode.
+// It is the caller's responsibility to close f when finished.
+// Closing c does not affect f, and closing f does not affect c.
+func (c *TCPConn) File() (f *os.File, err os.Error) { return c.fd.dup() }
+
 // DialTCP is like Dial but can only connect to TCP networks
 // and returns a TCPConn structure.
 func DialTCP(net string, laddr, raddr *TCPAddr) (c *TCPConn, err os.Error) {
@@ -281,3 +286,8 @@ func (l *TCPListener) Close() os.Error {
 
 // Addr returns the listener's network address, a *TCPAddr.
 func (l *TCPListener) Addr() Addr { return l.fd.laddr }
+
+// File returns a copy of the underlying os.File, set to blocking mode.
+// It is the caller's responsibility to close f when finished.
+// Closing c does not affect f, and closing f does not affect c.
+func (l *TCPListener) File() (f *os.File, err os.Error) { return l.fd.dup() }
index 89a074755b08667dd61c1e5a8cdc6aa72abb2001..0270954c176ddf89f7d4dd387ff416af200c9aaa 100644 (file)
@@ -274,3 +274,8 @@ func (c *UDPConn) BindToDevice(device string) os.Error {
        defer c.fd.decref()
        return os.NewSyscallError("setsockopt", syscall.BindToDevice(c.fd.sysfd, device))
 }
+
+// File returns a copy of the underlying os.File, set to blocking mode.
+// It is the caller's responsibility to close f when finished.
+// Closing c does not affect f, and closing f does not affect c.
+func (c *UDPConn) File() (f *os.File, err os.Error) { return c.fd.dup() }
index 93535130a2e7851e8577ac6d9a9e87e594012642..82c0b6d05b8d4f88c68852209dec0005d53fd4fa 100644 (file)
@@ -277,6 +277,11 @@ func (c *UnixConn) WriteTo(b []byte, addr Addr) (n int, err os.Error) {
        return c.WriteToUnix(b, a)
 }
 
+// File returns a copy of the underlying os.File, set to blocking mode.
+// It is the caller's responsibility to close f when finished.
+// Closing c does not affect f, and closing f does not affect c.
+func (c *UnixConn) File() (f *os.File, err os.Error) { return c.fd.dup() }
+
 // DialUnix connects to the remote address raddr on the network net,
 // which must be "unix" or "unixgram".  If laddr is not nil, it is used
 // as the local address for the connection.
@@ -369,6 +374,11 @@ func (l *UnixListener) Close() os.Error {
 // Addr returns the listener's network address.
 func (l *UnixListener) Addr() Addr { return l.fd.laddr }
 
+// File returns a copy of the underlying os.File, set to blocking mode.
+// It is the caller's responsibility to close f when finished.
+// Closing c does not affect f, and closing f does not affect c.
+func (l *UnixListener) File() (f *os.File, err os.Error) { return l.fd.dup() }
+
 // ListenUnixgram listens for incoming Unix datagram packets addressed to the
 // local address laddr.  The returned connection c's ReadFrom
 // and WriteTo methods can be used to receive and send UDP