1
0
mirror of https://github.com/golang/go synced 2024-10-01 03:28:32 -06:00

net: provide public access to file descriptors

Fixes #918.

R=rsc, rog, brainman
CC=golang-dev
https://golang.org/cl/2904041
This commit is contained in:
Keith Rarick 2010-11-05 14:02:03 -04:00 committed by Russ Cox
parent 5df5d3276d
commit a144e3ec36
5 changed files with 44 additions and 0 deletions

View 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
}

View 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)
}

View 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() }

View 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() }

View 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