> Date: Thu, 24 Sep 2026 07:52:12 -0700
> From: Collin Funk <[email protected]>
>
> It has been a while since I looked at pipe-f2.sh, but I remember coming
> to the conclusion that it was a NetBSD bug [1]. I never managed to
> create a simple reproduction to report, and feel a bit bad just sending
> over a long test case and asking them to fix it for me.
I would be curious to see how you came to that conclusion!
I compared ktraces of coreutils tail(1) and NetBSD's tail(1) in a
reduced test case of:
$ rm -f out exp
$ mkfifo out
$ echo 1 >out & echo=$!
$ ktrace tail -f out >exp & tail=$!
$ wait $echo
$ sleep 5
$ kill $tail
$ wait $tail
$ kdump -R | grep -v mmap | tail -20
I inserted a sleep and used kdump -R (show relative timestamps) so you
can see where the time is spent -- you'll see that it is only in the
very last read _after_ the fifo reports EOF.
Here's the output for NetBSD tail(1):
29985 29985 tail 0.000000764 RET __fstat50 0
29985 29985 tail 0.000006412 CALL read(3,0x730a164d1000,0x1000)
29985 29985 tail 0.000006292 GIO fd 3 read 2 bytes
"1\n"
29985 29985 tail 0.000000355 RET read 2
29985 29985 tail 0.000008934 CALL read(3,0x730a164d1000,0x1000)
29985 29985 tail 0.000001248 GIO fd 3 read 0 bytes
""
29985 29985 tail 0.000000207 RET read 0
29985 29985 tail 0.000001842 CALL write(1,0x730a164c0000,2)
29985 29985 tail 0.000005768 GIO fd 1 wrote 2 bytes
"1\n"
29985 29985 tail 0.000000270 RET write 2
29985 29985 tail 0.000003033 CALL kqueue
29985 29985 tail 0.000000944 RET kqueue 4
29985 29985 tail 0.000003459 CALL __kevent50(4,0x7f7fff2787a0,1,0,0,0)
29985 29985 tail 0.000001950 RET __kevent50 0
29985 29985 tail 0.000001287 CALL read(3,0x730a164d1000,0x1000)
29985 29985 tail 5.002272721 RET read RESTART
29985 29985 tail 0.000001185 PSIG SIGTERM SIG_DFL: code=SI_USER sent by
pid=5142, uid=1000)
Here's the output for coreutils tail(1);
16702 16702 tail 0.000012542 CALL open(0x7f7fffb6ad6f,0,0)
16702 16702 tail 0.000000728 NAMI "out"
16702 16702 tail 0.000003938 RET open 3
16702 16702 tail 0.000002380 CALL __fstat50(3,0x7f7fffb6a630)
16702 16702 tail 0.000000792 RET __fstat50 0
16702 16702 tail 0.000008315 CALL read(3,0x73aa41997500,0x400)
16702 16702 tail 0.000089855 GIO fd 3 read 2 bytes
"1\n"
16702 16702 tail 0.000000594 RET read 2
16702 16702 tail 0.000003812 CALL read(3,0x73aa41997500,0x400)
16702 16702 tail 0.000018985 GIO fd 3 read 0 bytes
""
16702 16702 tail 0.000000385 RET read 0
16702 16702 tail 0.000017100 CALL __fstat50(1,0x7f7fffb6a280)
16702 16702 tail 0.000001326 RET __fstat50 0
16702 16702 tail 0.000006237 CALL __fstat50(1,0x7f7fffb6a590)
16702 16702 tail 0.000000623 RET __fstat50 0
16702 16702 tail 0.000001737 CALL read(3,0x7f7fffb6a0b0,0x400)
16702 16702 tail 5.002260818 RET read RESTART
16702 16702 tail 0.000001380 PSIG SIGTERM SIG_DFL: code=SI_USER sent by
pid=29372, uid=1000)
As you can see, the process wakes up promptly to receive the zero-byte
return from read() indicating EOF in both cases, but the coreutils
tail(1) doesn't write anything after that -- it fstats stdout a couple
times, but then goes right back to reading until SIGTERM is delivered.
So this is not consistent with the hypothesis laid out at
<https://lists.gnu.org/archive/html/coreutils/2026-04/msg00129.html>
that NetBSD fails to indicate EOF promptly.