The "problem" is that a FIFO without data hangs on open(2), until data is available, the same goes for the initial read of the file.
We could work around this by adding the O_NONBLOCK flag to a separate open(2) call, but I know that this flag is frowned upon. Since gnu tail shows the same behaviour I'm not sure if it's worth doing. Since I'm not claiming to know all the edge-cases of O_NONBLOCK you could carry this diff locally at your own risk. Or maybe if other developers feel strong about this and are braver than me when it comes to O_NONBLOCK it might go somewhere. martijn@ On Wed, 2022-06-08 at 22:09 -0400, Philippe Meunier wrote: > Hi, > > Try: > > $ mkfifo fifo1 fifo2 > $ tail -f fifo1 fifo2 > > Then in another terminal: > > $ while true; do /bin/echo aaaa > fifo1; done > > and... nothing happens. I would have expected tail(1) to start showing the > content of fifo1 as soon as content became available but no, it just keeps > waiting. > > Then in another terminal: > > $ while true; do /bin/echo bbbb > fifo2; done > > and then tail(1) starts showing output as expected, alternating between > fifo1 and fifo2. > > The interesting part is that, once tail(1) has started producing output, > you can interrupt and restart one or both of the "aaaa" and / or "bbbb" > loops and tail(1) always does what you'd expect. It seems that it's only > at the very start that tail(1) doesn't produce any output until content is > available in both fifos. > > I tried various things like -n 0 and -c 0 but to no avail. > > Another interesting thing to try: > - start the "aaaa" loop > - interrupt the "aaaa" loop > - start the "bbbb" loop > and tail(1) starts displaying output. > > But if you try: > - start the "bbbb" loop > - interrupt the "bbbb" loop > - start the "aaaa" loop > then tail(1) still doesn't show any output, until you start the "bbbb" loop > for a second time! > > So at the very start, not only does tail(1) seem to expect content in both > fifos before it start showing output, but it also seems to expect the > content to appear in the specific order indicated on the tail(1) command > line. > > I assume this is a bug in tail(1)? > > Cheers, > > Philippe > > Index: tail.c =================================================================== RCS file: /cvs/src/usr.bin/tail/tail.c,v retrieving revision 1.22 diff -u -p -r1.22 tail.c --- tail.c 4 Jan 2019 15:04:28 -0000 1.22 +++ tail.c 9 Jun 2022 12:33:24 -0000 @@ -37,6 +37,7 @@ #include <err.h> #include <errno.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -56,7 +57,7 @@ main(int argc, char *argv[]) off_t off = 0; enum STYLE style; int ch; - int i; + int i, fd; char *p; if (pledge("stdio rpath", NULL) == -1) @@ -154,8 +155,12 @@ main(int argc, char *argv[]) if (argc) { for (i = 0; *argv; i++) { tf[i].fname = *argv++; - if ((tf[i].fp = fopen(tf[i].fname, "r")) == NULL || - fstat(fileno(tf[i].fp), &(tf[i].sb))) { + /* + * Use O_NONBLOCK to avoid hanging on FIFO. + */ + fd = open(tf[i].fname, O_RDONLY | O_NONBLOCK); + if (fd == -1 || (tf[i].fp = fdopen(fd, "r")) == NULL || + fstat(fd, &(tf[i].sb))) { ierr(tf[i].fname); i--; continue;