Skip to content

Register the descriptor returned by TCPServer and UNIXServer#sysaccept - #9818

Open
sampokuokkanen wants to merge 2 commits into
jruby:masterfrom
sampokuokkanen:sysaccept-register-fd
Open

sampokuokkanen wants to merge 2 commits into
jruby:masterfrom
sampokuokkanen:sysaccept-register-fd

Conversation

@sampokuokkanen

Copy link
Copy Markdown
Contributor

TCPServer#sysaccept returned the raw fileno without registering it, so Socket.for_fd and TCPSocket.for_fd on it failed with EBADF and IOError.

UNIXServer#sysaccept built a UNIXSocket only to return its fd, and when that object was collected its finalizer closed the caller's descriptor.

Both now wrap the accepted channel in a ChannelFD, which registers the descriptor and sets close-on-exec, without an IO object to finalize.

Also added a null check in UNIXServer's accept, like TCPServer#sysaccept already has.

Found by @albertalef in #9813 (comment).

TCPServer#sysaccept returned the raw fileno without registering it, so
Socket.for_fd and TCPSocket.for_fd on it failed with EBADF and IOError.

UNIXServer#sysaccept built a UNIXSocket only to return its fd, and when
that object was collected its finalizer closed the caller's descriptor.

Both now wrap the accepted channel in a ChannelFD, which registers the
descriptor and sets close-on-exec, without an IO object to finalize.
While another thread has the server channel nonblocking, for IO.select
or accept_nonblock, it can take the connection between our select and
accept, and jnr-unixsocket's accept then returns null. accept wrapped
that into a UNIXSocket with no connection, and sysaccept raised a
NullPointerException. Go back to waiting instead, like TCPServer#sysaccept.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant