peo@cpsc6a.UUCP (Paul E. Olson) (12/12/85)
*** REPLACE THIS LINE WITH YOUR MESSAGE ***
Could someone please explain to me why the printf() family of
functions cause errno to be set to 25 (not a typewritter) when output
is redirected to either a file or a pipe. I know that the problem comes
from the C lib function isatty() when ioctl() fails. So, maybe the real
question should be - Is this an oversight? It would seem to me that redirecting
printf output does not constitute an error and that the functions _findbuf()
and setbuf() should take care to reset errno to 0 if line buffering is not
needed. At first I thought it was a bug, but now I'm not so sure. I get the
same results using:
SYS 5.0.5 on a 3B20
SYS 5.2 on a 3B5
SYS 5.2 on a 3B2
Xenix 3.0 on an Altos
4.2BSD on an 11/780
AT&T PC7300
The following illustrates the problem.
/* foo.c */
extern int errno;
main()
{
printf("errno=%d\n", errno);
printf("errno=%d\n", errno);
}
$ cc foo.c -o foo
$ foo
errno=0
errno=0
$ foo >bar
$ cat bar
errno=0
errno=25
$
All this started while chasing a bug is some software I was porting.
Thanks in advance for any and all comments.
Paul E. Olson
ihnp4!cpsc6a!peo
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (12/16/85)
isatty() is not the only culprit; other "section 3" C library routines also can set errno as a side-effect of successful operation. (This can legitimately be considered a misfeature, but that's the way it is.) You should only test errno when a system call (section 2 routine) returns an error indication. Nothing in the C library should ever set errno to 0, although if the misfeature were to be corrected some routines would have to save and restore errno.
apm@iclbra.UUCP (Andy Merritt) (12/17/85)
> *** REPLACE THIS LINE WITH YOUR MESSAGE *** > > Could someone please explain to me why the printf() family of > functions cause errno to be set to 25 (not a typewritter) when output > is redirected to either a file or a pipe. I know that the problem comes > from the C lib function isatty() when ioctl() fails. So, maybe the real > question should be - Is this an oversight? It would seem to me that redirecting The problem is a common misunderstanding about the use of errno. The value in errno is useful if, and only if, the call has returned a value indicating failure. This value is commonly -1, and sometimes NULL for functions returning pointers. The Intro(2) manual page says: "Errno is not cleared on successful calls, so it should be tested only after an error has been indicated" The documentation I have for printf further states that it, fprintf and sprintf return the number of characters transmitted, or a negative value if an output error was encountered. Hope this helps. UUCP: ...seismo!mcvax!ukc!stc!iclbra!apm MAIL: Andrew Merritt, ICL, Lovelace Rd, Bracknell, Berkshire
daemon@houligan.UUCP (12/20/85)
In article <119@cpsc6a.UUCP>, peo@cpsc6a.UUCP (Paul E. Olson) writes: > Could someone please explain to me why the printf() family of functions > cause errno to be set to 25 (not a typewritter) when output is > redirected to either a file or a pipe. I know that the problem comes > from the C lib function isatty() when ioctl() fails. So, maybe the real > question should be - Is this an oversight? Once again, this discussion rears its ugly head. Check your manual page "INTRO(2)" for how "errno" is to be used. Specifically the phrase: "... errno should be tested ONLY after an error has occurred ..." (emphasis added). Please note that the value of "errno" upon return from a library routine is specifically UNDEFINED unless: 1. The documentation for the routine specifically states that an error code is returned in "errno" (this is untrue of the "printf" family), 2. The routine DOES NOT RETURN an error condition (a return of -1 in most cases). What this all boils down to is: Don't examine the value contained in "errno" UNLESS the called routine specifically indicated an error has occurred by its return value. --tgi while (--tgi) /* my mind continues to decay */ ; /* even though I do nothing.. */ {brl-bmd,ccvaxa,pur-ee,sun}!csd-gould!midas!tgi (Craig Strickland @ Gould) 305/587-2900 x5014 CompuServe: 76545,1007 Source: BDQ615 MCIMail: 272-3350 (echo ".ft B"; echo ".ps 999"; echo "$disclaimer") | troff -t # :-)
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (12/21/85)
> The problem is a common misunderstanding about the use of errno. The value > in errno is useful if, and only if, the call has returned a value indicating > failure. This value is commonly -1, and sometimes NULL for functions > returning pointers. The Intro(2) manual page says: "Errno is not cleared on > successful calls, so it should be tested only after an error has been indicated" > > The documentation I have for printf further states that it, fprintf and sprintf > return the number of characters transmitted, or a negative value if an output > error was encountered. Close, but not quite. `errno' is only set by unsuccessful SYSTEM CALLS (and some math library routines, alas). Therefore, failure of printf() does not imply that errno will correctly indicate the reason for failure.
tim@ism780c.UUCP (Tim Smith) (12/25/85)
> Could someone please explain to me why the printf() family of > functions cause errno to be set to 25 (not a typewritter) when output > is redirected to either a file or a pipe. I know that the problem comes Because a file or a pipe is not a typewriter? -- Tim Smith sdcrdcf!ism780c!tim || ima!ism780!tim || ihnp4!cithep!tim
jsdy@hadron.UUCP (Joseph S. D. Yao) (12/26/85)
As Gwyn and Merritt point out, the value of errno is not guaranteed to be meaningful except under certain circumstances, e.g., failed system calls. The reason it gets set at all inside printf() is that printf() checks stdout for tty-ness and, if it is not a tty, buffers output. Otherwise, depending on the version of UNIX, it line-buffers it or does not buffer it at all. Again depending on the version of UNIX, roughly the same may be true of stdin. I believe (and I know Doug'll hit me if I'm wrong) that stderr is always unbuffered. -- Joe Yao hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}