From owner-freebsd-standards@FreeBSD.ORG Fri Mar 28 23:06:39 2008 Return-Path: Delivered-To: freebsd-standards@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9603C1065675 for ; Fri, 28 Mar 2008 23:06:39 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from fallbackmx09.syd.optusnet.com.au (fallbackmx09.syd.optusnet.com.au [211.29.132.242]) by mx1.freebsd.org (Postfix) with ESMTP id 08DDC8FC21 for ; Fri, 28 Mar 2008 23:06:37 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail02.syd.optusnet.com.au (mail02.syd.optusnet.com.au [211.29.132.183]) by fallbackmx09.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id m2SJV33Z022216 for ; Sat, 29 Mar 2008 06:31:04 +1100 Received: from besplex.bde.org (c220-239-252-11.carlnfd3.nsw.optusnet.com.au [220.239.252.11]) by mail02.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id m2SJUdhX015985 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 29 Mar 2008 06:30:40 +1100 Date: Sat, 29 Mar 2008 06:30:39 +1100 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Ed Schouten In-Reply-To: <20080328130357.GC51074@hoeg.nl> Message-ID: <20080329051836.V36709@besplex.bde.org> References: <20080328130357.GC51074@hoeg.nl> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: FreeBSD Standards Subject: Re: Ambiguous sentence in POSIX onlinepubs 11.1.11 X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Mar 2008 23:06:39 -0000 On Fri, 28 Mar 2008, Ed Schouten wrote: > The last couple of days I've been reading the POSIX onlinepubs now and > then to find out how my new mpsafe TTY implementation conforms to POSIX. Also run a conformance test. I tested the sio and cy drivers with NIST PCTS. POSIX now has its own conformance tests but I haven't tried those. > In section 11.1.11, there is the following sentence: > > "The last process to close a terminal device file shall cause > any output to be sent to the device and any input to be > discarded." > > This sentence is quite ambiguous. It could mean: > > "The last process to close a terminal device file shall cause > any output to be sent to the device, [but] any input to be > discarded." > > but it could also mean: > > "The last process to close a terminal device file shall cause > any output [which still has] to be sent to the device and any > input to be discarded." > > I know FreeBSD currently implements the first behaviour. It drains > output on closure, but how can we know for sure this is the correct > behaviour? I think it means the first behaviour. If it meant flushing output then it shouldn't say "to be sent to the device". Anyway, waiting for output to drain has been the default in BSD since at least 1988, and standards shouldn't change that. The rationale in 1966 contradicts the above slightly (though POSIX.1-1996 says the above too). From the PCTS source code quoting POSIX.memble (the quote matches POSIX.1-1996 B.7.1.11): %%% POSIX.1 is silent on whether a close() will block on waiting for transmission to drain, or even if a close() might cause a flush of pending output. If the application is concerned about this, it should call the appropriate function, such as tcdrain(), to ensure the desired behavior. %%% This contradicts both interpretations of the standard, since if the standard requires output to be sent then sending it but flushing it is an unreasonable interpretation, while if the standard requires flushing then it is not silent. The standard is only silent on whether sending requires full blocking like tcdrain() would do and BSD almost does (old BSD can block forever, wasting lots of phone connection or modem resources, but FreeBSD has a timeout; the implementation of this timeout is not quite right, since it affects tcdrain() (not just last-close from exit() where it is most needed), and it gives an undocumented errno for tcdrain()). The rationale in POSIX.1.2001-draf7 is quite different from the above: %%% 2823 A.11.1.11Closing a Terminal Device File 2824 IEEE Std 1003.1-200x does not specify that a close( ) on a terminal device file include the 2825 equivalent of a call to tcflow(fd,TCOON). 2826 An implementation that discards output at the time close( ) is called after reporting the return 2827 value to the write( ) call that data was written does not conform with IEEE Std 1003.1-200x. An 2828 application has functions such as tcdrain( ), tcflush( ), and tcflow( ) available to obtain the detailed 2829 behavior it requires with respect to flushing of output. 2830 At the time of the last close on a terminal device, an application relinquishes any ability to exert 2831 flow control via tcflow( ). %%% This mentions tcflow() but not tcdrain(). I interpret this as meaning that the wording is now considered unambiguous and unsilent, since tcflow() is irrelevant if the output must be flushed, but tcflow() is very relevant if the output has been stopped by tcflow(...TCOOF) -- then the program has asked for an infinite blockage. Ah, it gives one case where output must not be flushed -- if write() has succeeded. This covers the usual case of buffered writes. I don't see how there can be any output "to be sent" unless a previous buffered write has queued it and has succeeded, except possibly in some non-POSIX exceptional cases involving things like revoke(). Otherwise, last-close cannot be called while there are writes in progress. 11.1.11 in .2001-draft7 and 7.1.11 in .1996 also require HUPCL to work. The timing of asserting HUP (dropping DTR) is unclear. The receiver is required to flush input when it sees the HUP so draining output after asserting HUP would be useless. BSD drains output first. The PCTS sources (file 7.1.1_69.c) have more comments about this. The test seems to cover generation of hangup on the sender according to HUPCL and the receiver's processing of hangup. Hmm, one of the comments claims that draining/flushing of output is irrelevant in the HUPCL case, since the receiver is required to flush input. But this depends on the timing. The receiver is quite likely to handle hangup asynchronously before handling all input, so it would flush input even if the sender generates the hangup synchronously after flushing all the output, but it might not. Bruce