Hi, It has been some time and I did not get any response for the below question.
I am not subscribed to the NetBSD tech-kern mailing list but I have been checking the mailing list archive to make sure that I have not missed any responses. I disabled the code I had identified below in fifo_vnops.c and I could see that when read is called after receiving an EINTR, it returns zero and my parent program shows success. Can someone please let me know if this make sense? or should I try something else? or should I be asking this in some other mailing list? One question which I have been asking myself is that why someone else have not seen it. The only answer I could come up with is, that we are using FIFO which are names pipe (i.e. a file) and they are mostly used by two different processes. Parent-child normally uses PIPE or socket-pair to communicate and so may be no-one has seen this issue yet. Thanks in advance. Regards, Bharat On Wed, Dec 7, 2011 at 9:52 PM, Bharat Joshi <bharat.j...@gmail.com> wrote: > 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