Re: perror() changes the orientation of stderr to byte-oriented mode if stderr is not oriented yet.

Craig Howland <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
On 07/02/2018 07:36 AM, Eric Blake wrote:
> On 07/02/2018 05:28 AM, Corinna Vinschen wrote:
>
>>> By the way, I have noticed that psignal() and psiginfo() also have the
>>> same problem. psignal() belongs to newlib, so the same strategy can
>>> be applied. However, what can we do for psiginfo()? Only the FreeBSD
>>> route may be the answer...
>>
>> I guess the simplest solution is to use the FreeBSD/OpenBSD method
>> all the time.
>
> If nothing else, it at least would mean fewer variations in practice, 
> regardless of whether POSIX is changed to relax things (the POSIX discussion 
> has been started, but it may be a while before any conclusion is reached; 
> what's more, the C99 standard tried to address it in TC2 
> (http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_276.htm) but then withdrew 
> that in TC3 because the attempted resolution conflicted with the POSIX wording 
> (http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_322.htm).
>
      To make it explicit, as looking back in the thread I don't see it stated 
directly:  The FreeBSD/OpenBSD method is for perror()/psignal()/psiginfo() to 
use write() to the stderr file number.  Supporting this as perhaps a good way to 
go, the discussion thread on POSIX has pointed out that "the historic [perror()] 
implementation calls write(2) to STDERR_FILENO."
      This sounds like a good solution for newlib from the points of view of 1) 
staying small and uncomplicated, 2) producing behavior consistent with 
historical systems, 3) not changing the stream orientation.  If does have a 
potential drawback of possibly changing behavior since it would effectively mix 
stream and write output from the application level whereas now it is only 
stream.  On the other hand, since perror() does print a complete line, the 
behavior should not change if the stream is either unbuffered or line buffered, 
but could be different only if fully buffered.  However, the since stderr 
default "is not fully buffered", the number of applications affected would 
probably be in the minority.  (A subjective statement, but I expect it would be 
very hard to quantify.)
      It is a bad solution from the point of view that the C standard (C11 N1570 
7.21.10.4#2) says that perror() "writes a sequence of characters to the standard 
error stream".  That is, using write does not write to the stream, itself, as 
required.  So the question becomes, is this a real problem, or only a 
theoretical problem? Since write ultimately is called for writes to the stream, 
how real of a problem is it?  As already noted, there is one settings case 
(fully buffered) in which actual behavior could be different.
      I think that one way of quantifying the general problem is that we have a 
choice between 3 options.   1) violate a POSIX CX extension (present state), 2)  
remain strictly C and POSIX CX compliant (which the present thread has 
characterized as making the code a lot more complicated), or 3) violate the C 
standard (albeit in a way that can be argued to be meaningless).
      (To be very picky, the preceding evaluations as to how settings might 
affect output are based on using newlib as it stands. Obviously, if anyone has 
partially "hacked" the stream method for efficiency purposes, things would 
differ more.  But this is an inherent danger in such edits, and should be 
understood as a risk by anyone who does them.  (I have done such in the past in 
highly-constrained systems, but I knew I might be stuck at a specific newlib 
version when I did so.))
                 Craig
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.