On Mon, Jun 26, 2023 at 03:51:59PM +0200, Jan Kara wrote: > On Mon 26-06-23 14:57:55, Ahelenia Ziemiańska wrote: > > On Mon, Jun 26, 2023 at 02:19:42PM +0200, Ahelenia Ziemiańska wrote: > > > > splice(2) differentiates three different cases: > > > > if (ipipe && opipe) { > > > > ... > > > > if (ipipe) { > > > > ... > > > > if (opipe) { > > > > ... > > > > > > > > IN_ACCESS will only be generated for non-pipe input > > > > IN_MODIFY will only be generated for non-pipe output > > > > > > > > Similarly FAN_ACCESS_PERM fanotify permission events > > > > will only be generated for non-pipe input. > > Sorry, I must've misunderstood this as "splicing to a pipe generates > > *ACCESS". Testing reveals this is not the case. So is it really true > > that the only way to poll a pipe is a sleep()/read(O_NONBLOCK) loop? > So why doesn't poll(3) work? AFAIK it should... poll returns instantly with revents=POLLHUP for pipes that were closed by the last writer. Thus, you're either in a hot loop or you have to explicitly detect this and fall back to sleeping, which defeats the point of polling: -- >8 -- #define _GNU_SOURCE #include <errno.h> #include <fcntl.h> #include <poll.h> #include <stdio.h> #include <unistd.h> int main() { char buf[64 * 1024]; struct pollfd pf = {.fd = 0, .events = POLLIN}; size_t consec = 0; for (ssize_t rd;;) { while (poll(&pf, 1, -1) <= 0) ; if (pf.revents & POLLIN) { while ((rd = read(0, buf, sizeof(buf))) == -1 && errno == EINTR) ; fprintf(stderr, "\nrd=%zd: %m\n", rd); } if (pf.revents & POLLHUP) { if (!consec++) fprintf(stderr, "\n\tPOLLHUPs"); fprintf(stderr, "\r%zu", consec); } else consec = 0; } } -- >8 -- And -- >8 -- $ ./rdr < fifo rd=12: Success 1779532 POLLHUPs rd=5: Success 945087 POLLHUPs rd=12: Success ^C -- >8 -- corresponding to -- >8 -- $ cat > fifo abc def ghi ^D $ echo zupa > fifo $ cat > fifo as dsaa asd ^C -- >8 --
Attachment:
signature.asc
Description: PGP signature