Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.1 6/24/83 (MC840302); site mcvax.UUCP
Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!think!harvard!seismo!mcvax!aeb
From: aeb@mcvax.UUCP (Andries Brouwer)
Newsgroups: net.bugs.4bsd,net.unix-wizards
Subject: Re: Bug in isatty (BSD4.2)
Message-ID: <744@mcvax.UUCP>
Date: Tue, 9-Jul-85 23:56:09 EDT
Article-I.D.: mcvax.744
Posted: Tue Jul  9 23:56:09 1985
Date-Received: Thu, 11-Jul-85 20:36:38 EDT
References: <726@mcvax.UUCP> <112@desint.UUCP>
Reply-To: aeb@mcvax.UUCP (Andries Brouwer)
Organization: CWI, Amsterdam
Lines: 30
Xref: watmath net.bugs.4bsd:1597 net.unix-wizards:13769

In article <112@desint.UUCP> geoff@desint.UUCP (Geoff Kuenning) writes:
>Um, I think errno is specified to be valid only if putchar returns the
>constant EOF.  Thus, the code should be:
>
>	if (putchar ('\n') == EOF)
>		perror ("putchar");
>

Unfortunately, this is not true.
errno is set by system calls, but not by the stdio library routines.
Thus, when a stdio library routine fails it may be that errno
contains useful information (in case the failure was due to a
system call error return), but it may also be that errno contains
garbage (in case the library routine detected the error itself).
Thus, fopen can fail when all _iob entries are taken; putc can fail
when writing to a stream that has not been opened for writing, etc.

This means that you cannot reliably use the stdio routines when you want
to do error recovery.

Example:
#include 
main(){
	putchar('\n');			/* sets errno via isatty() */
	fclose(stdout);			/* make next putchar fail */
	if(putchar('\n') == EOF)
		perror("putchar");	/* produce garbage */
}
Again, the call  a.out > /dev/null  will produce  putchar: no such device,
and  a.out | ...  produces  putchar: operation not supported on socket.