Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Given any epoll TCP socket event, if EPOLLRDHUP=0 and EPOLLIN=1; is a subsequent call to read()/recv() guaranteed to return a read size unequal to 0?

Ask Question

EPOLLRDHUP (since Linux 2.6.17)

Stream socket peer closed connection, or shut down writing half of connection. (This flag is especially useful for writing simple code to detect peer shutdown when using Edge Triggered monitoring.)

From the manual of recv:

If no messages are available to be received and the peer has performed an orderly shutdown, recv() shall return 0.

It seems to me then that both of the above cover the same scenarios, and that as long as I catch EPOLLRDHUP events first, I should never receive a read() or recv() of length 0 (and thus don't need to bother checking for such). But is this guaranteed to be true?

If you get an event with EPOLLRDHUP=1 then just close the connection right away without reading. If you get an event with EPOLLRDHUP=0 and EPOLLIN=1 then go ahead and read, but you should be prepared to handle the possibility of recv() still returning 0, just in case. Perhaps a FIN arrives after you got EPOLLIN=1 but before you actually call recv() .

"Perhaps a FIN arrives after you got EPOLLIN=1 but before you actually call recv()." But even if a FIN arrives at such a moment, recv() would return something bigger than 0, right? Because the FIFO pipe still contains whatever elicited EPOLLIN=1 in the first place. Will May 10, 2013 at 0:54 Great answer. I would amend it to say, ".. go ahead and read, but you should be prepared to handle the possibility of recv() still returning 0 or -1 , just in case." selbie May 10, 2013 at 1:20 @WillBuddha: if you check the result of epoll for EPOLLERR=1 and/or EPOLLHUP=1 to detect error events, do you still check recv() for -1? Yes, because it is good error handling. Same thing with EPOLLRDHUP=1 and recv()=0 . Is it likely to happen? No. Is it possible to happen? Yes. Maybe the kernel screws up internally. Maybe it gets things out of order. Who knows. Better to cover your @$$, just in case. Remy Lebeau May 10, 2013 at 1:58 I don't agree with this answer. I think the part with "If you get an event with EPOLLRDHUP=1" is wrong, because it happened to me to get both EPOLLIN and EPOLLRDHUP at once, if the peer sent something and immediately closed the connection. So, there was data to read. haelix Nov 6, 2014 at 15:58 @haelix I am looking at this right now, and can confirm this. A fast write/close on localhost will result in 0x2001 (RDHUP|IN), but with data in the pipe, and read returning first the data, then zero. Also for example a SIGPIPE will result in 0x2019 (RDHUP|HUP|ERR|IN) with a read returning zero. In this edge case you could skip the read and just act on the RDHUP, but in the case above you prob want the data sent, which in my mind makes RDHUP pretty useless since you anyway need to handle this when reading. Fredrik Widlund May 31, 2015 at 12:40

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question . Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers .