It would likely be better to always continue trying to read until EAGAIN
is returned, even if the read returned less than the requested amount,
as implied here:
"The function do_use_fd() uses the new ready file descriptor until
EAGAIN is returned by either read(2) or write(2). An event driven state
machine application should, after having received EAGAIN, record its
current state so that at the next call to do_use_fd() it will continue
Though, this is somewhat contradicted by the FAQ section:
"the condition that the read/write I/O space is exhausted can be
detected by checking the amount of data read/write from/to the target
file descriptor. For example, if you call read(2) by asking to read a
certain amount of data and read(2) returns a lower number of bytes, you
can be sure to have exhausted the read I/O space for such file descriptor."
The man page has been recently edited to avoid confusion:
Q9 Do I need to continuously read/write a file descriptor until
EAGAIN when using the EPOLLET flag (edge-triggered behavior) ?
A9 Receiving an event from epoll_wait(2) should suggest to you
that such file descriptor is ready for the requested I/O operation.
You must consider it ready until the next (non-blocking) read/write
yields EAGAIN. When and how you will use the file descriptor is
entirely up to you.
For packet/token-oriented files (e.g., datagram socket, terminal
in canonical mode), the only way to detect the end of the read/write
I/O space is to continue to read/write until EAGAIN.
For stream-oriented files (e.g., pipe, FIFO, stream socket), the
condition that the read/write I/O space is exhausted can also be
detected by checking the amount of data read from / written to the
target file descriptor. For example, if you call read(2) by asking to
read a certain amount of data and read(2) returns a lower number
of bytes, you can be sure of having exhausted the read I/O space for
the file descriptor. The same is true when writing using write(2).
(Avoid this latter technique if you cannot guarantee that the
monitored file descriptor always refers to a stream-oriented file.)