On Mar 4, 2004, at 9:17 PM, Robert Norris wrote:
On Thu, Mar 04, 2004 at 07:39:48PM -0600, Scott Lamb wrote:On Mar 4, 2004, at 6:44 PM, Robert Norris wrote:The connection is only closed if the socket is readable and there's no
bytes waiting. The results of select()/poll() are undefined unless they
return successfully.
I'm saying that I believe select(), poll(), etc. can return
successfully with an indication that a socket is available for read()
or write() when in fact it is not. In addition to the page I mentioned,
there was a discussion about this on linux-kernel a while ago, I
believe. They said (from memory) that (a) you should always use
non-blocking IO with select and (b) you should not be surprised if a
read() or write() returns -1/EWOULDBLOCK, even immediately after a
select() that indicates readability/writability for that descriptor. In
this situation, I believe a call to return the number of waiting bytes
would return 0; there'd be no way to distinguish the EOF from the
spurious return until you actually do the read().
Interesting. I've never actually seen select() and friends do this, but of course there's lots of broken OSes out there.
Well, they don't even consider it to be broken. I've found the message in question:
<http://groups.google.com/groups?q=select+hint+group: linux.kernel&hl=en&lr=lang_en&ie=UTF-8&oe=UTF -8&group=linux.kernel&c2coff=1&safe=off&selm=20030609031009%2414ba%40gat ed-at.bofh.it&rnum=1>
I'm not familiar with a read on a closed socket returning anything other
than 0. It doesn't make sense to me that it would return -1/EWOULDBLOCK
- if its closed, then a read should never block - it should just return
0.
I've never seen that, either.
If select() reports that a socket is readable when its not, then I suppose FIONREAD _might_ return 0 (I honestly don't know),
I would expect it would be similar to what happens if no select() has been made and nothing is available. Doesn't it return 0 then?
but I would
still expect recv(MSG_PEEK) to return -1/EWOULDBLOCK (sinces it still
does a read). So surely that would be a safe way to determine if there's
anything in the buffer?
Ahh. I'd forgotten about recv(..., MSG_PEEK). That might work.
I want a basic I/O event layer that tells the application
above it when something interesting happens on a socket (ie something to
read, ready to write, closed). If the event layer has to read data to
find this out, then this abstraction doesn't work.
Is distinguishing close really that important? What select() tells you is that you can probably do a read() or write() without getting -1/EWOULDBLOCK. Both of those are true when the socket is closed. I guess I just don't understand the importance of making finer distinctions than that before you actually try to do something.
Scott