kern/170203: [kern] piped dd' s don' t behave sanely when dealing with a fifo

Bruce Evans brde at optusnet.com.au
Sun Jul 29 06:48:49 UTC 2012


On Sun, 29 Jul 2012, David Xu wrote:

> FIFO pipe is quite broken! Beside the bug you have reported, there is another 
> bug,
> when a writer closed the pipe, select() on reader side will never return !
> I am curious that so long time, nobody found the bugs, does it because FIFO
> is seldom used by people ?

That might be a feature (intentional).  Many people (apparently there are
some who actually use fifos :-) wanted select() to not see EOF on fifos,
since select() has no way to return POLLHUP and naive applications
except that when select() on an input descriptor returns successfully
there is data available, so they tend to spin read()ing EOF.

FreeBSD has most of my old POLLINIGNEOF mistake for ignoring EOF, and
newer complications to do things wrong more like other OS's.  I only
remember a couple of details.  Other OSs gave us a context-senstive
EOF state that is confusingly different from related states for sockets
(CANTSENDMORE/CANTRCVMORE).  EOF should not be ignored in so many cases
now.  POLLINIGNEOF is no longer set by the kernel to force ignoring
EOF.  It remains as bogus compatibility cruft for user foot-shooting.
POLLHUP now mostly works for poll() (poll() has less problems than
select() because poll() can return this, but poll() didn't understand
it for most file types).

I think the case where the writer goes away is supposed to work now
(return from select()).  The sticky state is mostly for the case of
a reader for which there has never been a writer.  People want select()
to block then (normally open() blocks, but you can open with O_NONBLOCK
and then want to block waiting for a writer).  The difficulty is with
"has never been".  When the last writer goes away, this should break
the connection for old readers.  This is easy to implement.  But what
about for new readers?  Should they see the same sticky EOF state as
old readers, if the old ones have not gone away, and thus not block?
What about when the old readers finish going away after the new reader
starts?  What about races in this?

The new fifo implementation may have broken this, but there are some
poll/select tests in src/tools/regression/poll that should have found
major regressions.  Not all of my kernel code for this were committed,
so some of the Linux compatibly tests never passed in FreeBSD (some
sanity ones never passed in Linux).

Bruce


More information about the freebsd-bugs mailing list