Issue #19012 has been updated by byroot (Jean Boussier).
Apparently we can get this via `getsockopt(fd, SOL_SOCKET, SO_TYPE, &type,
&length);`, the question being how portable it is.
----------------------------------------
Bug #19012: BasicSocket#recv* methods return an empty packet instead of nil on closed
connections
https://bugs.ruby-lang.org/issues/19012#change-100437
* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
`man recvmsg(2)` states:
Return Value
These calls return the number of bytes received, or -1 if an error occurred. The return
value will be 0 when the peer has performed an orderly shutdown.
But somehow the entire `receiv` family of methods in Ruby seem to interpret `0` as empty
string instead of "EOF".
```ruby
require 'socket'
puts "=== pipes ==="
r, w = IO.pipe
r.read_nonblock(1, exception: false) # => :wait_readable
w.close
r.read_nonblock(1, exception: false) # => nil (EOF)
puts "=== sockets ===="
r, w = UNIXSocket.socketpair
r.read_nonblock(1, exception: false) # => :wait_readable
r.recvmsg_nonblock(1, exception: false) # => :wait_readable
r.recv_nonblock(1, exception: false) # => :wait_readable
w.close
r.read_nonblock(1, exception: false) # => nil (EOF)
r.recvmsg_nonblock(1, exception: false) # => ["", #<Addrinfo:
empty-sockaddr SOCK_STREAM>, 128]]
r.recvmsg # => ["", #<Addrinfo: empty-sockaddr SOCK_STREAM>, 0]]
r.recv_nonblock(1, exception: false) # => ""
```
### Expected behavior
I would expect `recvmsg_nonblock`, `recvmsg`, `recv_nonblock` and `recv` to return `nil`
when the connection is closed.
--
https://bugs.ruby-lang.org/