Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Jun 2012 04:57:29 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Andrey Chernov <ache@FreeBSD.org>
Cc:        svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org, Pawel Jakub Dawidek <pjd@FreeBSD.org>, freebsd-arch@FreeBSD.org
Subject:   Re: svn commit: r236582 - head/lib/libc/stdlib
Message-ID:  <20120606043731.D1124@besplex.bde.org>
In-Reply-To: <20120605130922.GE13306@vniz.net>
References:  <201206042134.q54LYoVJ067685@svn.freebsd.org> <20120605074741.GA1391@garage.freebsd.pl> <20120605130922.GE13306@vniz.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 5 Jun 2012, Andrey Chernov wrote:

> On Tue, Jun 05, 2012 at 09:47:42AM +0200, Pawel Jakub Dawidek wrote:
>>>   "The setting of errno after a successful call to a function is
>>>   unspecified unless the description of that function specifies that
>>>   errno shall not be modified."
>>
>> Very interesting. However free(3) is always successful. Maybe we need
>> more context here, but the sentence above might talk about functions
>> that can either succeed or fail and such functions do set errno on
>> failure, but we don't know what they do to errno on success - they
>> sometimes interact with the errno, free(3) never does.
>
> According to Austing Group interpretation, this setence talks about
> funtions which always succeed too, please see
> http://austingroupbugs.net/view.php?id=385

This has very little to do with POSIX.  It is a basic part of Standard
C that the C library may, at its option, clobber errno, gratuitously
or otherwise.  From n869.txt:

        [#3]  The  value of errno is zero at program startup, but is
        never set to zero by any library function.159)  The value of
        errno  may  be  set  to  nonzero  by a library function call
        whether or not there is an error, provided the use of  errno
        is not documented in the description of the function in this
        International Standard.

Use of errno is not documented for free(); thus free() is permitted to
clobber errno.

POSIX may require errno to not be clobbered, especially for its functions.
It probably shouldn't do this for Standard C library functions like free(),
since this would be an extension and any use of the extension would give
unnecessarily unportanle code.

>> I aware that my interpretation might be too wishful, but it is pretty
>> obvious to save errno value when calling a function that can eventually
>> fail - when we save the errno we don't know if it will fail or not, so
>> we have to do that, but requiring to save errno when calling a void
>> function that can't fail is simply silly and complicates the code
>> without a reason.

This has very little to do with success or failure.  It does complicate
the code for callers, but actually simplifies the library.  Since most
libary functions aren't required to preserve errno, they can call each
other without having save and restore errno when they call each other.

> It still can fail due to internal errors, it just not returns failure.
> For internal errors POSIX states that errno state is unspecified.
>
>> I agree that the standards aren't clear, but if saving errno around
>> free(3) is the way to go, then I'm sure we have much more problems in
>> our code, even if it is not suppose to be portable it should be correct
>> - we never know who and when will take the code and port it.
>
> Currently they are pretty clear in that moment, although I agree that if
> POSIX says it should not modify errno, the life will be easy. Lets look at
> their further movement, since they are already aware of this specific
> problem.

They are perfectly clear.

>> I guess what I'm trying to say here is that this is much bigger change
>> than it looks and we should probably agree on some global rule here.
>
> ...which not violate standards.

Yes, its completion is a very large and ugly change.  realpath() is a
POSIX interface, so any code that implements or uses it can safely assume
POSIX requirements.  But non-POSIX code can only safely assume Standard
C requirements.  OTOH, the libary can assume anything that it wants and
implements for itself, since it is the implementation so it can make
free() easy to use for itself, with any extensions that aren't incompatible
with Standard C.  Since free() is allowed to clobber errno, it is also
allowed to do a null clobber as a compatible extension.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120606043731.D1124>