On Tue, Jan 26, 2010 at 11:23:18AM -0800, Blair Zajac wrote:
> On 01/26/2010 10:32 AM, Stefan Sperling wrote:
> >I've been told some time ago, by long-time unix hackers,
> >that clearning errno is usually not necessary, one of the few
> >exceptions to this rule being the strtol() family of functions.
> >I didn't account for this exception when writing the log message,
> >which was wrong.
> My understand is that if you ever need to check the errno then you
> should set it 0 yourself because system and library calls will not
> set it to 0 for you.
Usually you won't compare errno to zero, but to some known
value which the function in question will set errno to in case
of failure. The failure itself is not indicated via errno, but
through other means, like the return value. Examining errno then
gives you the reason for the failure.
E.g. if open(2) fails, it indicates failure by returning -1.
You would then check errno for a number of values, e.g. ENOTDIR,
ENAMETOOLONG, ENOENT, EACCES, etc. to find out what happened.
But in case open returns a valid fd, you can just go on and
use the fd. errno won't contain interesting information.
> How is strtol() different?
If the parsed number is out of range, strtol() uses errno as the
only channel to signal an error. Actually, the same applies to
apr_strtoi64(), so I really should not have made the change which
prompted this discussion! A better interface would probably require
allocating the converted number and returning a pointer to it.
Then it could return NULL on failure, instead of something
which looks like a number.
For reference: http://www.openbsd.org/cgi-bin/man.cgi?query=strtol
Ensuring that a string is a valid number (i.e., in range and containing
no trailing characters) requires clearing errno beforehand explicitly
since errno is not changed on a successful call to strtol(), and the re-
turn value of strtol() cannot be used unambiguously to signal an error:
errno = 0;
lval = strtol(buf, &ep, 10);
if (buf == '\0' || *ep != '\0')
if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
Received on 2010-01-26 20:45:25 CET