Date: Sat, 25 Mar 2006 05:10:26 GMT From: Bruce Evans <bde@zeta.org.au> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/94772: FIFOs (named pipes) + select() == broken Message-ID: <200603250510.k2P5AQR1047032@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/94772; it has been noted by GNATS. From: Bruce Evans <bde@zeta.org.au> To: Oliver Fromme <olli@lurza.secnetix.de> Cc: bug-followup@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200603250510.k2P5AQR1047032>