Hi! Consider the following programs: -- >8 -- ==> ino.c <== #define _GNU_SOURCE #include <stdio.h> #include <sys/inotify.h> #include <unistd.h> int main() { int ino = inotify_init1(IN_CLOEXEC); inotify_add_watch(ino, "/dev/fd/0", IN_MODIFY); char buf[64 * 1024]; struct inotify_event ev; while (read(ino, &ev, sizeof(ev)) > 0) { fprintf(stderr, "%d: mask=%x, cook=%x, len=%x, name=%.*s\n", ev.wd, ev.mask, ev.cookie, ev.len, (int)ev.len, ev.name); fprintf(stderr, "rd=%zd\n", read(0, buf, sizeof(buf))); } } ==> se.c <== #define _GNU_SOURCE #include <stdio.h> #include <sys/sendfile.h> int main() { ssize_t rd, acc = 0; while ((rd = sendfile(1, 0, 0, 128 * 1024 * 1024)) > 0) acc += rd; fprintf(stderr, "se=%zd: %m\n", acc); } ==> sp.c <== #define _GNU_SOURCE #include <fcntl.h> #include <stdio.h> int main() { ssize_t rd, acc = 0; while ((rd = splice(0, 0, 1, 0, 128 * 1024 * 1024, 0)) > 0) acc += rd; fprintf(stderr, "sp=%zd: %m\n", acc); } -- >8 -- By all means, ./sp | ./ino and ./se | ./ino should be equivalent, right? -- >8 -- $ make se sp ino $ mkfifo fifo $ ./ino < fifo & [1] 230 $ echo a > fifo $ echo a > fifo 1: mask=2, cook=0, len=0, name= rd=4 $ echo c > fifo 1: mask=2, cook=0, len=0, name= rd=2 $ ./se > fifo abcdef 1: mask=2, cook=0, len=0, name= asd ^D se=11: Success rd=11 1: mask=2, cook=0, len=0, name= rd=0 $ ./sp > fifo abcdefg asd dsasdadadad sp=24: Success $ < sp ./sp > fifo sp=25856: Success $ < sp ./sp > fifo ^C $ echo sp > fifo ^C -- >8 -- Note how in all ./sp > fifo cases, ./ino doesn't wake up! Note also how, thus, we've managed to fill the pipe buffer with ./sp (when it transferred 25856), and now we can't /ever/ write there again (both splicing and normal writes block, since there's no space left in the pipe; ./ino hasn't seen this and will never wake up or service the pipe): so we've effectively "denied service" by slickily using a different syscall to do the write, right? I consider this to be unexpected behaviour because (a) obviously and (b) sendfile() sends the inotify event. Happens on my linus checkout (v6.4-rc7-234-g547cc9be86f4) and bookworm (6.1.27-1).
Attachment:
signature.asc
Description: PGP signature