X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/9385eb3d10ebe5eb398c52040ec3dbfba9b0cdcf..5f1254882f242514d4ceaf1ecebb140dcc2a511d:/string/FreeBSD/strerror.c diff --git a/string/FreeBSD/strerror.c b/string/FreeBSD/strerror.c index 71c514e..46144e3 100644 --- a/string/FreeBSD/strerror.c +++ b/string/FreeBSD/strerror.c @@ -10,10 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -35,27 +31,35 @@ static char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -__FBSDID("$FreeBSD: src/lib/libc/string/strerror.c,v 1.11 2003/01/03 16:44:42 mike Exp $"); +__FBSDID("$FreeBSD: src/lib/libc/string/strerror.c,v 1.16 2007/01/09 00:28:12 imp Exp $"); +#if defined(NLS) +#include +#endif + +#include #include -#include #include +#include +#include -#define UPREFIX "Unknown error: " +#define UPREFIX "Unknown error" /* * Define a buffer size big enough to describe a 64-bit signed integer * converted to ASCII decimal (19 bytes), with an optional leading sign - * (1 byte); finally, we get the prefix and a trailing NUL from UPREFIX. + * (1 byte); finally, we get the prefix, delimiter (": ") and a trailing + * NUL from UPREFIX. */ -#define EBUFSIZE (20 + sizeof(UPREFIX)) +#define EBUFSIZE (20 + 2 + sizeof(UPREFIX)) +#ifndef BUILDING_VARIANT /* * Doing this by hand instead of linking with stdio(3) avoids bloat for * statically linked binaries. */ -static void -errstr(int num, char *buf, size_t len) +__private_extern__ void +__errstr(int num, char *uprefix, char *buf, size_t len) { char *t; unsigned int uerr; @@ -69,31 +73,75 @@ errstr(int num, char *buf, size_t len) } while (uerr /= 10); if (num < 0) *--t = '-'; - strlcpy(buf, UPREFIX, len); + *--t = ' '; + *--t = ':'; + strlcpy(buf, uprefix, len); strlcat(buf, t, len); } int strerror_r(int errnum, char *strerrbuf, size_t buflen) { + int retval = 0; +#if defined(NLS) + int saved_errno = errno; + nl_catd catd; + catd = catopen("libc", NL_CAT_LOCALE); +#endif - if (errnum < 1 || errnum >= sys_nerr) { - errstr(errnum, strerrbuf, buflen); - return (EINVAL); + if (errnum < 0 || errnum >= sys_nerr) { + __errstr(errnum, +#if defined(NLS) + catgets(catd, 1, 0xffff, UPREFIX), +#else + UPREFIX, +#endif + strerrbuf, buflen); + retval = EINVAL; + } else { + if (strlcpy(strerrbuf, +#if defined(NLS) + catgets(catd, 1, errnum, sys_errlist[errnum]), +#else + sys_errlist[errnum], +#endif + buflen) >= buflen) + retval = ERANGE; } - if (strlcpy(strerrbuf, sys_errlist[errnum], buflen) >= buflen) - return (ERANGE); - return (0); + +#if defined(NLS) + catclose(catd); + errno = saved_errno; +#endif + + return (retval); } +__private_extern__ char *__strerror_ebuf = NULL; +#else /* BUILDING_VARIANT */ +__private_extern__ void __errstr(int, char *, size_t); + +extern char *__strerror_ebuf; +#endif /* !BUILDING_VARIANT */ + char * strerror(int num) { - static char ebuf[EBUFSIZE]; + // Dynamically allocate a big buffer to receive the text then shrink it + // down to the actual size needed. + size_t ebufsiz = NL_TEXTMAX; - if (num > 0 && num < sys_nerr) - return ((char *)sys_errlist[num]); - errno = EINVAL; - errstr(num, ebuf, sizeof(ebuf)); - return (ebuf); + if (__strerror_ebuf == NULL) { + __strerror_ebuf = calloc(1, ebufsiz); + if (__strerror_ebuf == NULL) { + return NULL; + } + } + + if (strerror_r(num, __strerror_ebuf, ebufsiz) != 0) { +#if !__DARWIN_UNIX03 + errno = EINVAL; +#endif + } + return __strerror_ebuf; }