Skip to content

Commit a144e3e

Browse files
krrsc
authored andcommitted
net: provide public access to file descriptors
Fixes #918. R=rsc, rog, brainman CC=golang-dev https://golang.org/cl/2904041
1 parent 5df5d32 commit a144e3e

File tree

5 files changed

+44
-0
lines changed

5 files changed

+44
-0
lines changed

src/pkg/net/fd.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,3 +517,17 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (nfd *netFD, err os.
517517
}
518518
return nfd, nil
519519
}
520+
521+
func (fd *netFD) dup() (f *os.File, err os.Error) {
522+
ns, e := syscall.Dup(fd.sysfd)
523+
if e != 0 {
524+
return nil, &OpError{"dup", fd.net, fd.laddr, os.Errno(e)}
525+
}
526+
527+
// We want blocking mode for the new fd, hence the double negative.
528+
if e = syscall.SetNonblock(ns, false); e != 0 {
529+
return nil, &OpError{"setnonblock", fd.net, fd.laddr, os.Errno(e)}
530+
}
531+
532+
return os.NewFile(ns, fd.sysfile.Name()), nil
533+
}

src/pkg/net/fd_windows.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,8 @@ func init() {
373373
initErr = os.NewSyscallError("WSAStartup", e)
374374
}
375375
}
376+
377+
func (fd *netFD) dup() (f *os.File, err os.Error) {
378+
// TODO: Implement this
379+
return nil, os.NewSyscallError("dup", syscall.EWINDOWS)
380+
}

src/pkg/net/tcpsock.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,11 @@ func (c *TCPConn) SetNoDelay(noDelay bool) os.Error {
208208
return setNoDelay(c.fd, noDelay)
209209
}
210210

211+
// File returns a copy of the underlying os.File, set to blocking mode.
212+
// It is the caller's responsibility to close f when finished.
213+
// Closing c does not affect f, and closing f does not affect c.
214+
func (c *TCPConn) File() (f *os.File, err os.Error) { return c.fd.dup() }
215+
211216
// DialTCP is like Dial but can only connect to TCP networks
212217
// and returns a TCPConn structure.
213218
func DialTCP(net string, laddr, raddr *TCPAddr) (c *TCPConn, err os.Error) {
@@ -281,3 +286,8 @@ func (l *TCPListener) Close() os.Error {
281286

282287
// Addr returns the listener's network address, a *TCPAddr.
283288
func (l *TCPListener) Addr() Addr { return l.fd.laddr }
289+
290+
// File returns a copy of the underlying os.File, set to blocking mode.
291+
// It is the caller's responsibility to close f when finished.
292+
// Closing c does not affect f, and closing f does not affect c.
293+
func (l *TCPListener) File() (f *os.File, err os.Error) { return l.fd.dup() }

src/pkg/net/udpsock.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,8 @@ func (c *UDPConn) BindToDevice(device string) os.Error {
274274
defer c.fd.decref()
275275
return os.NewSyscallError("setsockopt", syscall.BindToDevice(c.fd.sysfd, device))
276276
}
277+
278+
// File returns a copy of the underlying os.File, set to blocking mode.
279+
// It is the caller's responsibility to close f when finished.
280+
// Closing c does not affect f, and closing f does not affect c.
281+
func (c *UDPConn) File() (f *os.File, err os.Error) { return c.fd.dup() }

src/pkg/net/unixsock.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,11 @@ func (c *UnixConn) WriteTo(b []byte, addr Addr) (n int, err os.Error) {
277277
return c.WriteToUnix(b, a)
278278
}
279279

280+
// File returns a copy of the underlying os.File, set to blocking mode.
281+
// It is the caller's responsibility to close f when finished.
282+
// Closing c does not affect f, and closing f does not affect c.
283+
func (c *UnixConn) File() (f *os.File, err os.Error) { return c.fd.dup() }
284+
280285
// DialUnix connects to the remote address raddr on the network net,
281286
// which must be "unix" or "unixgram". If laddr is not nil, it is used
282287
// as the local address for the connection.
@@ -369,6 +374,11 @@ func (l *UnixListener) Close() os.Error {
369374
// Addr returns the listener's network address.
370375
func (l *UnixListener) Addr() Addr { return l.fd.laddr }
371376

377+
// File returns a copy of the underlying os.File, set to blocking mode.
378+
// It is the caller's responsibility to close f when finished.
379+
// Closing c does not affect f, and closing f does not affect c.
380+
func (l *UnixListener) File() (f *os.File, err os.Error) { return l.fd.dup() }
381+
372382
// ListenUnixgram listens for incoming Unix datagram packets addressed to the
373383
// local address laddr. The returned connection c's ReadFrom
374384
// and WriteTo methods can be used to receive and send UDP

0 commit comments

Comments
 (0)