The FIFO is opened by the shell, but the opening of it is blocking until the FIFO is opened for writing by some other process. The Since redirections are processed before the execution of the command, the program is therefore not even executed until the shell's open() call returns. This is documented behaviour for the open() C library function (used by the shell):
O_NONBLOCKWhen opening a FIFO with
O_RDONLYorO_WRONLYset:
- If
O_NONBLOCKis set, anopen()for reading-only shall return without delay. Anopen()for writing-only shall return an error if no process currently has the file open for reading.
- If
O_NONBLOCKis clear, anopen()for reading-only shall block the calling thread until a thread opens the file for writing. Anopen()for writing-only shall block the calling thread until a thread opens the file for reading.
So the shell is obviously not using O_NONBLOCK when it's opening the FIFO.
Solution:
cat fifo | program
cat reads from the FIFO until end-of-file, then exits.
tail -f fifo | program
tail reads from the FIFO until end-of-file, then hangs around to wait for more until terminated.
Which of these is best suited to your situation depends a bit on what's writing to the FIFO at the other end, and how it does the writing.
Third solution involves having the program opening the FIFO when needed.
According to the Rationale section on sh, a shell must set standard input to blocking because...
If the shell did not reset this flag, it would immediately terminate because no input data would be available yet and that would be considered the same as end-of-file.