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

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

> On Wed, Jun 06, 2012 at 04:57:29AM +1000, Bruce Evans wrote:
>> 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.
>
> POSIX feels itself like they own all Standard C functions now. See

Not really.  They can extend anything they want...

> "Resolved state" text for upcoming standard there:
>
> "At line 30583 [XSH free DESCRIPTION], add a paragraph with CX shading:
>
> The free() function shall not modify errno if ptr is a null pointer
> or a pointer previously returned as if by malloc() and not yet
> deallocated.

...but the have to mark it as an extension, as they do here.

> At line 30591 [APPLICATION USAGE], add a new paragraph:
>
> Because the free() function does not modify errno for valid pointers, it
> is safe to use it in cleanup code without corrupting earlier errors, ..."

This is essentially unusable (so a bad idea).  Instead of unconditionally
saving and restoring errno around calls to free(), portable POSIX code
can soon use a messy ifdef to avoid doing this in some cases, but still
has to do it in other cases.  The results is just bloat and complexity
at the source level:

#if _POSIX_VERSION < mumble
 	int sverrno;
#endif
 	...
 	if (wantfree)
#if _POSIX_VERSION < mumble
 	{			/* I made these braces condtional ... */
 		sverrno = errno;
#endif
 		free(p);
#if _POSIX_VERSION < mumble
 		errno = sverrno;
 	}			/* ... to maximise the ugliness */
#endif

>> 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.
>
> Yes, it is safe for free() itself to save errno and still stay compliant
> with both current and upcoming POSIX and with Standard C. But any code
> which rely on that is compliant with upcoming POSIX only. Since people
> don't want mass changes in that area, this is some sort of compromise
> acceptable for me (in case free() itself will save/restore errno, of
> course).

libc has lots of magic non-conforming code.  A little more won't hurt.

However, free() is currently not careful about errno.  It begins with
an optional utrace() call, and this can in theory fail with errno ENOMEM
even if there are no bugs in malloc() (all other errors from utrace()
indicate bugs in the caller, assuming that the list of errnos in its man
page is complete).  malloc.c makes a few other sys(lib?)calls and never
saves errno.  I don't know if the others are reachable from free().

Bruce



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