Bug in isatty (all systems!)

M.J.Shannon mjs at eagle.UUCP
Mon Jul 29 01:46:28 AEST 1985


> > >  ... I designed a large software system around
> > > the assumption that errno was always valid and not set as a side-effect.
> > > It took me 6 months (admittedly, I wasn't looking hard) to figure out
> > > why I was always getting "not a typewriter" (because my open routine 
> > > was setting a struct bit to indicate tty/non-tty for every file).
> > 
> > My 4.2bsd manual describes this in the INTRO(2) section, right before the
> > list of errno values.  Just where would you prefer that it be mentioned?
> > RTFM!
> 
>   MY 4.2bsd manual says:
> 
>       ... An
>      error number is also made available in the external variable
>      _errno_, which is not cleared on successful calls.  Thus _errno_
>      should be tested only after an error has occurred.
> 
>   What does "not cleared on successful calls" mean to you?  To me, it
> means that if I set errno = 0 in the beginning of my program, it will
> stay zero until a system call _fails_, then it will stay non-zero long
> enough for me to do something about it.  Now if a perfectly successful
> operation sets errno and does not bother to clear it, how can I depend
> on errno as an indication that something went _wrong_?

All of the routines in section 2 (system calls) have a return value which
indicates that errno contains the reason why it failed.  There are also some
routines in section 3 which behave the same way.  They are all adequately
documented.  The suggestion to "RTFM" is absolutely correct.  You cannot depend
on errno to tell you that an error occurred; it only tells you what the *last*
error from one of those routines which sets errno (on detection of an error)
was.  A perfectly successful operation will not return an failure value, thus
errno should not be consulted to see what the non-error was.

>   Remember, TFM does not say anywhere that _successful_ operations set
> errno, which is what, in effect, happens here.  Or should the whole
> world know how fopen() is implemented, in order to decipher errno
> in context?

fopen() is not one of the routines which provides its failure reason in errno
(except by accident of implementation, and then only when it does fail).

>   If I did not dream of this, one of the proposed standards has a passage 
> to the effect that "function calls may set errno to arbitrary values, 
> as long as their effect on errno is _not_ documented".  In other words, 
> don't check errno after calling a library routine unless the manual says
> that it sets errno to something meaningful.  Sigh.

No, that sentence should read:
	In other words, don't check errno after calling a library routine
	unless it returns an error indication *and* the manual says that it
	sets errno to something meaningful.

> Alexis Dimitriadis
-- 
	Marty Shannon
UUCP:	ihnp4!eagle!mjs
Phone:	+1 201 522 6063



More information about the Net.bugs.usg mailing list