Date: Sun, 29 Jul 2012 16:48:39 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: davidxu@FreeBSD.org Cc: Garrett Cooper <yanegomi@gmail.com>, freebsd-bugs@FreeBSD.org Subject: Re: kern/170203: [kern] piped dd' s don' t behave sanely when dealing with a fifo Message-ID: <20120729161615.J1766@besplex.bde.org> In-Reply-To: <501482CD.6050708@gmail.com> References: <201207272150.q6RLo9ew012879@freefall.freebsd.org> <501482CD.6050708@gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120729161615.J1766>