Date: Thu, 13 Jan 2005 18:34:18 +1000 From: Stephen McKay <smckay@internode.on.net> To: Peter Jeremy <PeterJeremy@optushome.com.au> Cc: Stephen McKay <smckay@internode.on.net> Subject: Re: Background processes setting O_NONBLOCK on ttys Message-ID: <200501130834.j0D8YIEf007484@dungeon.home> In-Reply-To: <20050113074721.GC79646@cirb503493.alcatel.com.au> from Peter Jeremy at "Thu, 13 Jan 2005 18:47:21 %2B1100" References: <200501120949.j0C9nQCZ000573@dungeon.home> <200501121354.j0CDscrR002027@dungeon.home> <20050113074721.GC79646@cirb503493.alcatel.com.au>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thursday, 13th January 2005, Peter Jeremy wrote: >On Wed, 2005-Jan-12 23:54:38 +1000, Stephen McKay wrote: >>a) Rewrite file descriptor handling in libc_r so it does not set O_NONBLOCK >>on tty file descriptors unless it is in the foreground. I don't know how >>hard this would be, or whether it even applies to -current with its profusion >>of threading libraries. I'll leave this to those who believe in threading. > >In 4.x, threads are totally userland and rely on non-blocking I/O. If >background tty file descriptors block on I/O, the entire process will >block, not just the thread performing I/O. This is a major POLA violation. Maybe yes, maybe no. The process stops with SIGTTOU. Stopped is stopped. My view is that it's a POLA violation to allow other processes to fiddle with non-blocking mode behind your back. Anyway, this problem goes away if we can have O_NONBLOCK be per file descriptor rather than per file open. Then it doesn't matter if a threaded process changes its own copy of the tty descriptor. Until then, anyone who wants to can protect themselves with my patch. It's working fine for me. :-) >In 5.x and later, both kernel and userland threads exist. I am totally lacking in info on 5.x and 6.x threading. If we can get rid of O_NONBLOCK here (or if it's already gone), then the major problem is solved. And my code to prevent non-blocking being set by background processes can be committed. (Better safe than sorry.) >>b) Add new non-blocking read() and write() call variants and use them in >>the threading library instead of setting O_NONBLOCK. > >See aio_read(2), aio_write(2). These look hard to use. I can't see how they could replace nonblocking reads using O_NONBLOCK. Even if I add kqueue() to the mix I see problems. By the way, I found a note about this from the author of djbdns. He has much the same complaints I have. See http://cr.yp.to/unix/nonblock.html >>c) Make O_NONBLOCK be per file descriptor (like FD_CLOEXEC). Thus, >>descriptors produced from dup() (for example) would have their own O_NONBLOCK >>flag, just as two descriptors from separate open() calls have today. > It might be useful to see what one of the POSIX experts think about this. >FreeBSD, NetBSD, OpenBSD and Linux all explicitly state that dup(2) >copies O_NONBLOCK (though Solaris 10 doesn't). It is reasonably likely >that existing code relies on the documented behaviour and will therefore >break when you move O_NONBLOCK from the file to the file descriptor. You can still have dup() copy the O_NONBLOCK flag. That's probably sensible. But if you did "b = dup(a)" then changed the O_NONBLOCK flag on "b" you wouldn't see that reflected on "a" (unlike now). Even after sleeping on this, I think option c) is the right answer. Stephen.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200501130834.j0D8YIEf007484>