kern/94772: FIFOs (named pipes) + select() == broken

Bruce Evans bde at zeta.org.au
Sat Mar 25 05:10:27 UTC 2006


The following reply was made to PR kern/94772; it has been noted by GNATS.

From: Bruce Evans <bde at zeta.org.au>
To: Oliver Fromme <olli at lurza.secnetix.de>
Cc: bug-followup at freebsd.org
Subject: Re: kern/94772: FIFOs (named pipes) + select() == broken
Date: Sat, 25 Mar 2006 16:00:30 +1100 (EST)

 On Thu, 23 Mar 2006, Oliver Fromme wrote:
 
 > I have to correct myself slightly, and I have a few more
 > insights ...
 >
 > Oliver Fromme wrote:
 > > Bruce Evans wrote:
 > > > select() on a named pipe:
 > > > % selectp: state 0: expected set; got clear
 > > > [...]
 > > > Now there is an extra failure for state 0.  Some complications will be
 > > > required to fix this without breaking poll() on named pipe.  State 0 is
 > > > when the read descriptor is open with O_NONBLOCK and there has "never"
 > > > been a writer.  In this state, select() on the read descriptor must
 > > > succeed to conform to POSIX, but poll() on the read descriptor must
 > > > block to conform to Linux.  I think the Linux behaviour is what happens
 > > > naturally -- the socket isn't hung up so sopoll() won't set POLLHUP,
 > >
 > > Now that might be debatable.  SUSv3 says that POLLHUP means
 > > that the device is disconnected.  That doesn't sound like
 > > it should make a difference if there was a previous writer
 > > or not.
 >
 > SUSv3 says about POLLHUP:  "The device has been disconnected".
 > I suppose that "has been disconnected" is different from "is
 > disconnected".  I'm sorry, English is not my native language,
 > so I didn't notice that slight difference when I read that
 > page first.
 >
 > Thinking about it again, the Linux implementation seems to be
 > reasonable, and it's probably conformant with the standard
 > (even though the standard is somewhat fuzzy).
 
 It's fairly subtle even for a native speaker.  (I think it would look
 like a larger difference for a non-native speaker, but you know
 English too well :-).  It's not quite precise enough for a standard
 since the literal English meaning would cover all past disconnections
 (unless we consider a fifo to be a virtual device whose life began
 on the previous "first" open by a reader or a writer).
 
 > So I agree with you that FreeBSD should behave the same as
 > Linux in that regard.
 
 > I propose a new SBS_* flag for the so_rcv.sb_state mask.
 > Lets call it SBS_EOFNOHUP for now (I'm sure someone can
 > come up with a better name).  It will be set in fifo_open()
 > in the case O_RDONLY | O_NONBLOCK and no writers.  It will
 > be cleared in fifo_open() when someone opens the FIFO for
 > writing.  In fifo_poll_f(), POLLHUP will be replaced by
 > POLLIGNEOF in the result of soo_poll() if SBS_EOFNOHUP is
 > set.
 
 I'm not sure that SBS_EOFNOHUP is needed.  SBS_CANTRCVMORE might
 be sufficient.  It is cleared when someone opens the FIFO for
 writing.  Also, the O_NONBLOCK open for read() shouldn't be very
 different, since in addition to previously discussed reasons the
 SBS flags are per-socket so they can't be used to give different
 behaviour for a mix of nonblocking and blocking reads.
 
 > selscan() does not need to be changed.  It will handle
 > POLLIGNEOF just like POLLHUP, so select() won't block.
 >
 > pollscan() needs a slight change in order to remove
 > POLLIGNEOF from the result of the fo_poll() call.
 > I think POLLIGNEOF should not be exposed to userland.
 > Its sole purpose is to communicate the abovementioned
 > case from fifo_poll_f() to selscan(), and only those
 > two functions should use that flag.
 >
 > That should fix both select() and poll(), if I didn't
 > miss anything.
 >
 > What do you think?
 
 Good.  I'll reply to the mail that has the patch.
 
 Bruce


More information about the freebsd-bugs mailing list