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

Oliver Fromme olli at lurza.secnetix.de
Wed Mar 22 15:00:37 UTC 2006


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

From: Oliver Fromme <olli at lurza.secnetix.de>
To: bde at zeta.org.au (Bruce Evans)
Cc: bug-followup at freebsd.org
Subject: Re: kern/94772: FIFOs (named pipes) + select() == broken
Date: Wed, 22 Mar 2006 15:50:06 +0100 (CET)

 Thank you very much for your detailed explanations!
 
 Bruce Evans wrote:
  > On Tue, 21 Mar 2006, Oliver Fromme wrote:
  > > When a FIFO had been opened for reading and the writing
  > > process closes it, the reading process blocks in select(),
  > > even though the descriptor is ready for read().  If the
  > > select() call is omitted, read() returns 0 immediately
  > > indicating EOF.  But as soon as you use select(), it blocks
  > > and there is no chance to detect the EOF condition.
  > 
  > See also:
  > 
  > PR 76125 (about the same bug)
  > PR 76144 (about a related bug in poll())
  > PR 53447 (about a another or the same related bug in poll())
  > PR 34020 (about the inverse of the bug (return on non-EOF) for select()
  >            and poll())
 
 Thank you for pointing those out.
 
 Before sending my PR, I spent about 15 minutes using
 the PR search facility on www.freebsd.org, with various
 combinations of the words "FIFO", "pipe", "select" and
 "poll", but I didn't get any useful results.  It seems
 that the search CGI is broken.
 
  > Here is a program that tests more cases.  I made it give no output
  > (for no errors) under Linux-2.6.10.  It also gives no output for
  > the nameless pipe case under FreeBSD-4.10 and FreeBSD-oldcurrent
  > and for the named piped case under FreeBSD-4.10, but it fails with
  > (only) the error in this PR under FreeBSD-oldcurrent.  Please test
  > it on Solaris etc.  Compile it with -DNAMEDPIPE for the named pipe
  > case.
 
 It does not produce any output on Solaris 9, NetBSD 3.0,
 DEC UNIX 4.0D and Linux 2.4.32.  (I had to replace signal()
 with sigset() on Solaris, add a few missing #includes and
 write small replacements for err() and warnx().)
 
 (By the way, DEC UNIX 4.0D _does_ have a bug:  If the FIFO
 has O_NONBLOCK set and no writer has opened the FIFO, then
 select() doesn't block.  That's a violation of SUSv3/POSIX.
 However, that's not related to the bug described in this
 PR, and it doesn't seem to be checked by the test program.)
 
  > Quick fix (?): #defining POLLINIGNEOF as 0 in <sys/poll.h> should give the
  > FreeBSD-4.10 behaviour.
 
 In fact, I noticed the comment in fifo_vnops.c that mentions
 POLLINIGNEOF, but I wasn't sure if it's related to the bug.
 
 There's a small problem with that workaround:  When I'm
 distributing software (which is supposed to be portable
 across various UNIX and UNIX-like systems), it's somewhat
 ugly to tell the users that they have to modify a system
 header file before my software will work on FreeBSD.
 
 However, I get your point that a real fix is non-trivial.
 
  > Fix (?):
  > - actually implement returning POLLHUP in sopoll() and other places.  Return
  >    POLLHUP but not POLLIN for the pure-EOF case.  Return POLLIN* | POLLHUP
  >    for EOF-with-data.
  > - remove POLLINIGNEOF and associated complications in sopoll(), fifo_poll()
  >    and <sys/poll.h>
  > - change selscan() to check for POLLHUP so that POLLIN, POLLIN | POLLHUP
  >    and POLLHUP all act the same for select()
  > - remove POLLHUP from the comment in selscan().  Fix the rest of this
  >    comment or remove it (most backends are too broken to return poll flags
  >    if appropriate, and the comment only mentions one of the other poll flags
  >    that selscan() ignores)
  > - remove the corresponding comment in pollscan() since it is wrong and says
  >    nothing relevant (pollscan() just accepts whatever flags the backends set).
 
 I would be happy to help out, but I'm not familiar with
 that part of the kernel code.  I wouldn't even know how
 to start.  Also, I don't have a spare box running Current
 (I assume that such patches would have to go into Current
 first).  Or is the difference of that code between 6-Stable
 and Current very small?
 
 Best regards
    Oliver
 
 -- 
 Oliver Fromme,  secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing
 Dienstleistungen mit Schwerpunkt FreeBSD: http://www.secnetix.de/bsd
 Any opinions expressed in this message may be personal to the author
 and may not necessarily reflect the opinions of secnetix in any way.
 
 "anyone new to programming should be kept as far from C++ as
 possible;  actually showing the stuff should be considered a
 criminal offence" -- Jacek Generowicz


More information about the freebsd-bugs mailing list