[quagga-dev 8945] Re: [PATCH] check for errno after strtoul

James Carlson carlsonj at workingcode.com
Thu Nov 10 12:33:13 GMT 2011

On 11/10/11 07:16, David Lamparter wrote:
> On Thu, Nov 10, 2011 at 10:46:55AM +0100, Ulrich Weber wrote:
>> there are a couple of strtoul calls which check for ULONG_MAX
>> but not for errno == ERANGE.
>>    l = strtoul (str, &endptr, 10);
>> -  if (*endptr == '\0' || l == ULONG_MAX || l > UINT32_MAX)
>> +  if (*endptr == '\0' || (l == ULONG_MAX && errno == ERANGE) || l > UINT32_MAX)
>>      return 0;
> When checking errno in combination with an ambiguous return value like
> ULONG_MAX, please clear errno before the call. Otherwise, if errno
> happens to be ERANGE before the call, the code will mistakenly assume
> that an invalid value has been entered.

It's not actually ambiguous, because the return value from strtoul is
not and has never been the correct thing to check for errors.

For that function, if you care about errors, you *must* set errno to
zero before the call, and then check whether it's non-zero after.  I
suspect that the code above (and the change) is just wrong.

The Linux man page says:

 Since strtoul() can legitimately return 0 or LONG_MAX (LLONG_MAX for
 strtoull()) on both success and failure, the calling program should set
 errno to 0 before the call, and then determine if an error occurred by
 checking whether errno has a non-zero value after the call.

The Solaris man page says:

     Because 0 and ULONG_MAX are returned on error and  are  also
     valid  returns  on  success, an application wishing to check
     for error situations  should  set  errno  to  0,  then  call
     strtoul(), then check errno and if it is non-zero, assume an
     error has occurred.

Others are similar.  Don't change the constant; fix the code.

James Carlson         42.703N 71.076W         <carlsonj at workingcode.com>

More information about the Quagga-dev mailing list