[vox-tech] errno upon success (a real success)?

vox-tech@lists.lugod.org vox-tech@lists.lugod.org
Wed, 9 Oct 2002 23:21:06 -0400


On Wed, Oct 09, 2002 at 03:15:46PM -0700, Peter Jay Salzman wrote:
> i've read that system and library calls can set errno, even when they're
> successful.

Pete,

  in the event of an error errno is defined to contain a description of
what went wrong.  errno may be undefined after a library call returns 
success(*), don't check errno unless a function reports failure via it's
return code and don't call other library calls before checking errno
(or else you may clobber the real error).

*:
  I have thought that errno _was_ undefined after a successful call, 
but I can't point at anything that says so right now.

  I've just skimmed around in glibc and I can see extensive work happening
to save errno upon entering and to restore errno on exiting most of the 
libc functions.  so it looks like gnu libc tries to not have errno change 
unless a function fails.


> does anyone know of an example where errno is set upon success that may
> not be as much of a stretch as taking the square root of infinity?

  I can't think of any functions that are documented to set errno and
return successfully...
  Even the way I read sqrt and atan docs, they don't modify errno
on success.  thanks to their API using the function return value as
the computed output value and the return values being non-ints (and
equality comparison of floats is dangerous), they don't have an easy
way to return "we have a problem"... as far as I can tell from the docs
they modify errno only when there is an error.  if their API were like:
  int sqrt(double input, double *output);
were return 0 is success, then they wouldn't appear to 
"change errno on success", but they would be much more of a pain to use.

  
  While the relevant section of glibc-doc doesn't go so far as to say
errno is undefined after a successful call... it does suggest not checking
unless an error code is returned and suggests a method of handling
the math functions which can't return a proper error code (due to
API).

/usr/share/info/libc.info-2.gz
#Checking for Errors
#===================
#
#   Most library functions return a special value to indicate that they
#have failed.  The special value is typically `-1', a null pointer, or a
#constant such as `EOF' that is defined for that purpose.  But this
#return value tells you only that an error has occurred.  To find out
#what kind of error it was, you need to look at the error code stored in
#the variable `errno'.
[...]
#     The initial value of `errno' at program startup is zero.  Many
#     library functions are guaranteed to set it to certain nonzero
#     values when they encounter certain kinds of errors.  These error
#     conditions are listed for each function.  These functions do not
#     change `errno' when they succeed; thus, the value of `errno' after
#     a successful call is not necessarily zero, and you should not use
#     `errno' to determine _whether_ a call failed.  The proper way to
#     do that is documented for each function.  _If_ the call failed,
#     you can examine `errno'.
#
#     Many library functions can set `errno' to a nonzero value as a
#     result of calling other library functions which might fail.  You
#     should assume that any library function might alter `errno' when
#     the function returns an error.
[...]
#     There are a few library functions, like `sqrt' and `atan', that
#     return a perfectly legitimate value in case of an error, but also
#     set `errno'.  For these functions, if you want to check to see
#     whether an error occurred, the recommended method is to set `errno'
#     to zero before calling the function, and then check its value
#     afterward.

    TTFN,
      Mike