This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH 0/3] Fix wrong assumption about errno
On Thu, Dec 21, 2017 at 8:08 PM, Carlos O'Donell <carlos@redhat.com> wrote:
> On 12/21/2017 07:40 PM, Zack Weinberg wrote:
>> On Thu, Dec 21, 2017 at 2:54 PM, Aurelien Jarno <aurelien@aurel32.net> wrote:
>>> These 3 patches fixes the wrong assumption that a successful function
>>> does not change errno. POSIX explicitly says that applications should
>>> check errno only after failure (or if the function specification
>>> provides additional scenarios where it has a defined value).
>>
>> I like these changes in general, but there are a few specific cases
>> where functions _are_ guaranteed not to change the value of errno on
>> success, and application code relies on that. The one I remember off
>> the top of my head is the strto* family, where all possible return
>> values _could_ be the result of a successful parse, so you have to set
>> errno to 0 beforehand and then check it afterward. Please make sure
>> that your changes do not imply this is not the case.
>
> The CERT coding rules[1] cover the list. What you mention is called in-band
> error return, where the function error return cannot be disambiguated from a
> correct result.
>
> The manual clarification is more correct than we had before. We say that
> no function will set errno to zero, but may set it to non-zero when they
> succeed. This does not preclude what you are talking about with functions
> that have in-band error return.
Please reread what I said - it's subtler than that. The key point is
that there *are* functions in the GNU C Library that are guaranteed
*not* to set errno to a nonzero value unless they have actually
failed, such as strto*. It's well and good for the general discussion
of errno to talk about how *most* functions do not make this
guarantee, but they should not make it sound like *none* of them do,
and the specific documentation for the functions that do make that
guarantee should say so.
(N.B. neither C11 nor POSIX makes the above an explicit requirement
for strto*, as I read them, but it is a de facto requirement given the
documented idiom for checking for failure
// p is expected to be a C-string containing a number and nothing more
errno = 0;
val = strtol(p, &endp, 0);
if (p == endp || *endp || errno)
report_error();
.)
zw