net.Listener file descriptor

1,256 views
Skip to first unread message

Keith Rarick

unread,
Sep 26, 2010, 2:12:20 AM9/26/10
to golang-nuts
I have a net.Listener, and I'd like to know when an incoming
connection is available without actually accepting it.

I'd also like to start another process with the listening socket in
its initial set of file descriptors. (Similar to the behavior of
inetd, launchd, and systemd.)

Both of these would be easy to do with syscall.Select and os.ForkExec
if I could get access to the os.File from the Listener, but there
doesn't seem to be a way to do that.

(All of this goes for net.PacketConn as well.)

What should I do? I have the following options in mind:

1. Patch net to provide access to the underlying os.File of a
Listener.

2. Reimplement part of the net package in my own program. (Of course,
I'd prefer to avoid this option, but if this stuff really doesn't
belong in the official net package, then so be it.)

Which is best? Anything else I haven't thought of?

I'm willing to write patches and get them through review.

Thanks!

kr

Russ Cox

unread,
Sep 27, 2010, 10:27:52 AM9/27/10
to Keith Rarick, golang-nuts
On Sun, Sep 26, 2010 at 02:12, Keith Rarick <k...@xph.us> wrote:
> I have a net.Listener, and I'd like to know when an incoming
> connection is available without actually accepting it.
>
> I'd also like to start another process with the listening socket in
> its initial set of file descriptors. (Similar to the behavior of
> inetd, launchd, and systemd.)

Why not accept the connection and then start the process
with the new connection in its initial set of file descriptors.
That's what inetd does.

> Both of these would be easy to do with syscall.Select and os.ForkExec
> if I could get access to the os.File from the Listener, but there
> doesn't seem to be a way to do that.

That's a known issue. I'm planning to fix it this week.
You can't just expose the *os.File because it is in
non-blocking mode and will probably make other users
fail. Instead I plan to add a File() *os.File method to
the various low-level network types that gives you a
different file (that is, a different fd) for the network
connection, that one opened in blocking mode as most
programs expect.

You'd have to do a conversion to the specific
type and then call the file method: l.(*net.TCPListener).File().

Russ

Ian Lance Taylor

unread,
Sep 27, 2010, 12:46:44 PM9/27/10
to r...@golang.org, Keith Rarick, golang-nuts
Russ Cox <r...@golang.org> writes:

> That's a known issue. I'm planning to fix it this week.
> You can't just expose the *os.File because it is in
> non-blocking mode and will probably make other users
> fail. Instead I plan to add a File() *os.File method to
> the various low-level network types that gives you a
> different file (that is, a different fd) for the network
> connection, that one opened in blocking mode as most
> programs expect.
>
> You'd have to do a conversion to the specific
> type and then call the file method: l.(*net.TCPListener).File().

Or presumably something like

type FileInterface {
File() *os.File
}

f := l.(FileInterface).File()

Ian

Keith Rarick

unread,
Sep 27, 2010, 7:00:45 PM9/27/10
to r...@golang.org, golang-nuts
On Mon, Sep 27, 2010 at 7:27 AM, Russ Cox <r...@golang.org> wrote:
> Why not accept the connection and then start the process
> with the new connection in its initial set of file descriptors.
> That's what inetd does.

I'm starting a potentially stateful process that can accept
connections and act as a point of communication. Also, it might want
to handle many concurrent open connections, and having that many
processes (say, ~40K) would be significantly slower. For example,
memcached.

inetd actually does both of these, depending on the setting of wait or
nowait. I'm interested in the "wait" behavior.

> That's a known issue.  I'm planning to fix it this week.

Fantastic, then I'll just check again in a week. Thanks!

kr

Keith Rarick

unread,
Oct 29, 2010, 12:57:30 AM10/29/10
to r...@golang.org, golang-nuts
On Mon, Sep 27, 2010 at 4:00 PM, Keith Rarick <k...@xph.us> wrote:
> On Mon, Sep 27, 2010 at 7:27 AM, Russ Cox <r...@golang.org> wrote:
>> That's a known issue.  I'm planning to fix it this week.

This doesn't appear to be done yet, and I'd like to help out with a
patch. I have a couple of questions:

Is it sufficient to dup the fd, ensure the new fd is in blocking mode,
and then wrap it in an os.File?

Aside from net.TCPListener and net.UnixListener, are there other types
that should get this treatment? Such as net.TCPConn, net.UDPConn, and
net.UnixConn?

Should I open a ticket for this issue and put further discussion there?

kr

Albert Strasheim

unread,
Oct 29, 2010, 2:57:34 AM10/29/10
to Keith Rarick, golan...@googlegroups.com
Hello Keith

The issue is here:

http://code.google.com/p/go/issues/detail?id=918

I'm also interested in getting this fixed.

Regards

Albert

Reply all
Reply to author
Forward
0 new messages