Basically, if you're using epoll "correctly", then you should never have a situation of an unexpectedly empty epoll set. You should know when there is more to do or not. Well, or that's the theory at least. Let me review it:
You are using EPOLLET here (which is, imho, the right think in general). It means that the file descriptor 0 is removed from the epoll when it is returned in &ret
. At this point you should handle it by reading some amount of data from 0, as you do, but then "re-arming" it by adding again file descriptor 0 into the epoll (unless it was closed of course). For an example of how this is supposed to work, remove the inner loop and just do:
k = read(0, buf, 100);
reading a maximum of 100 bytes. The idea is that if you pipe a file bigger than that, it should go several times through the whole loop. In order to make this work, if k > 0, after you handle the k bytes, you need to call epoll_ctl(..EPOLL_CTL_ADD..)
again.
Note an annoying detail: it's possible occasionally that the read()
returns 0 bytes without meaning the file or socket is at the end. Check if errno == EAGAIN || errno == EWOULDBLOCK
. To detect that case, and then epoll_ctl(..EPOLL_CTL_ADD..)
again.