Hi, I am seeing a strange behaviour with the read on a FIFO. Here is what my application is doing:
1. Parent application is forking a child. 2. In child, a FIFO is opened in write-mode. This is a dummy open to make sure that the parent application does not block on open itself. 3. Child application is exec'ed. 4. In parent, a FIFO is opened in read-mode. After this, it gets into a loop where it calls read system call on this FIFO. This read blocks as child application is yet to start writing. 5. Child application opens the same FIFO again in write-mode and then start writing. 6. Parent process read whatever child process writes. Everything works perfectly. 7. Child application finally closes the FIFO once it is done. As there is still the dummy write FIFO opened, nothing happens. Parent is blocked on 'read' thinking there is more to come. 8. Child exits and a signal SIGCHILD is delivered to parent. 9. Parent process which was blocked on 'read' returns with EINTR. Now once this happens, parent again calls 'read'. The code in parent expects it to return 0 (EOF) if there is no more writers available. In this case, even though no more writers are avilable, parent gets blocked on 'read'. Please note that the parent process had not reaped the child process yet. I started debugging this and finally reached to a code in fifo_read() in sys/miscfs/fifofs/fifo_vnops.c where if so_receive() on read socket has not read anything, we reset the so_state for CANTRECVMORE. Following code is available there: >>> error = (*rso->so_receive)(rso, NULL, uio, NULL, NULL, NULL); /* * Clear EOF indication after first such return. */ if (uio->uio_resid == startresid) rso->so_state &= ~SS_CANTRCVMORE; >>> I think because of this code, when the read request comes again, kernel does not return 0 and instead blocks on read. With this, how will someone ever figure out when EINTR is coming for a genuine interrupt or for a EOF. If you need more details on this, please let me know. Thanks in advance, Bharat