From owner-freebsd-arch@FreeBSD.ORG Tue Apr 8 12:33:35 2003 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9429437B401; Tue, 8 Apr 2003 12:33:35 -0700 (PDT) Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2680543FBD; Tue, 8 Apr 2003 12:33:34 -0700 (PDT) (envelope-from bde@zeta.org.au) Received: from katana.zip.com.au (katana.zip.com.au [61.8.7.246]) by mailman.zeta.org.au (8.9.3/8.8.7) with ESMTP id FAA10944; Wed, 9 Apr 2003 05:33:30 +1000 Date: Wed, 9 Apr 2003 05:33:28 +1000 (EST) From: Bruce Evans X-X-Sender: bde@gamplex.bde.org To: Yar Tikhiy In-Reply-To: <20030408164614.GA7236@comp.chem.msu.su> Message-ID: <20030409044301.J628@gamplex.bde.org> References: <20030408164614.GA7236@comp.chem.msu.su> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: arch@freebsd.org Subject: Re: termios & non-blocking I/O X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Apr 2003 19:33:35 -0000 On Tue, 8 Apr 2003, Yar Tikhiy wrote: > ... > Let's consider a non-blocking file descriptor that correspons to a > terminal in raw mode. Let's also assume read(2) is issued on it > when there is no data to read. > > If for this terminal MIN > 0 and TIME == 0, read(2) will return -1 > and set errno to EAGAIN. > > OTOH, if MIN == 0 and TIME > 0, read(2) will return 0. > > While not in disagreement with POSIX[1], such a behaviour has at > least one unwelcome consequence: If a program has been compiled > with ``-pthread'', the TIME counter won't work on terminal descriptors > that are in blocking mode from the program's point of view -- read(2) > will instantly return 0 on them. That is because the following > scenario will happen: The spec is not very clear, but I think it means to say to return -1/EAGAIN (it says that first). I seem to have help break this in FreeBSD-1. Rev.1.17 of tty.c fixed the complementary bug of returning EWOULDBLOCK after a timeout, and rev.1.32 (the last commit to tty.c in FreeBSD-1) "finished" implementing MIN/TIME and didn't handle this case quite right. The MIN/TIME changes are all collected together with no history in rev.1.8 of tty.c in FreeBSD-2. > 1) libc_r sets non-blocking mode on a descriptor as soon as a device > is opened (that is how i/o in user-land threads work); > 2) the program sets the TIME counter through tcsetattr(3); > 3) the program issues read(2), which ends up in the actual read() > syscall, which in turn returns 0 to libc_r (assuming there is no > data to read); > 4) libc_r thinks this is the EOF indicator, so it instantly returns > 0 to the program; > 5) the program breaks. > > Notice, that MIN works right with libc_r since read() syscall will > return -1/EAGAIN, which is correctly understood by libc_r: it will > block the current thread until there is data to read. Does it keep the fd in non-blocking mode and wait for the data using select() or similar? This wouldn't work so well for TIME because select() doesn't really understand MIN/TIME; in particular, TIME has no effect on select() in the MIN == 0 && TIME > 0 case. I think libc_r would have to duplicate most of the kernel's MIN/TIME stuff to fake things properly. It correctly doesn't go near this. Bruce