diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2004-05-03 05:07:35 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2004-05-03 05:07:35 +0000 |
commit | db0d881c05796f2f89c6a66d7f233bcd6f34fd33 (patch) | |
tree | b7017fe5fc04ace96878ddc1506466905f8104dd /lib/libc | |
parent | f7f154acf56f5df54e624274b0f149947f987102 (diff) |
build the error message in strerror_r.c directly, avoiding one copy there.
handle a few subtle details caught by the regression tests: correct
termination, non copying if buffer length == 0, errno setting.
let all former users of __strerror go through strerror_r.
Work by Todd Miller and I. Okay millert@.
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/stdio/perror.c | 12 | ||||
-rw-r--r-- | lib/libc/string/__strerror.c | 105 | ||||
-rw-r--r-- | lib/libc/string/strerror.c | 14 | ||||
-rw-r--r-- | lib/libc/string/strerror_r.c | 110 |
4 files changed, 112 insertions, 129 deletions
diff --git a/lib/libc/stdio/perror.c b/lib/libc/stdio/perror.c index 68ab7f41151..b5e855014a6 100644 --- a/lib/libc/stdio/perror.c +++ b/lib/libc/stdio/perror.c @@ -28,7 +28,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: perror.c,v 1.5 2003/06/02 20:18:37 millert Exp $"; +static char rcsid[] = "$OpenBSD: perror.c,v 1.6 2004/05/03 05:07:34 espie Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -38,13 +38,6 @@ static char rcsid[] = "$OpenBSD: perror.c,v 1.5 2003/06/02 20:18:37 millert Exp #include <stdio.h> #include <string.h> #include <limits.h> -/* - * Since perror() is not allowed to change the contents of strerror()'s - * static buffer, both functions supply their own buffers to the - * internal function __strerror(). - */ - -extern char *__strerror(int , char *); void perror(s) @@ -63,7 +56,8 @@ perror(s) v->iov_len = 2; v++; } - v->iov_base = __strerror(errno, buf); + (void)strerror_r(errno, buf, sizeof(buf)); + v->iov_base = buf; v->iov_len = strlen(v->iov_base); v++; v->iov_base = "\n"; diff --git a/lib/libc/string/__strerror.c b/lib/libc/string/__strerror.c index 87b47b68e40..4512c0bea03 100644 --- a/lib/libc/string/__strerror.c +++ b/lib/libc/string/__strerror.c @@ -28,114 +28,19 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: __strerror.c,v 1.12 2004/05/01 10:52:59 espie Exp $"; +static char *rcsid = "$OpenBSD: __strerror.c,v 1.13 2004/05/03 05:07:34 espie Exp $"; #endif /* LIBC_SCCS and not lint */ -#ifdef NLS -#define catclose _catclose -#define catgets _catgets -#define catopen _catopen -#include <nl_types.h> -#endif - -#define sys_errlist _sys_errlist -#define sys_nerr _sys_nerr - -#include <errno.h> #include <limits.h> -#include <stdio.h> #include <string.h> -static size_t -__digits10(unsigned int num) -{ - size_t i = 0; - - do { - num /= 10; - i++; - } while (num != 0); - - return i; -} - -void -__itoa(int num, char *buffer, size_t start, size_t end) -{ - size_t pos; - unsigned int a; - int neg; - - if (num < 0) { - a = -num; - neg = 1; - } - else { - a = num; - neg = 0; - } - - pos = start + __digits10(a); - if (neg) - pos++; - - if (pos < end) - buffer[pos] = '\0'; - else - buffer[end-1] = '\0'; - pos--; - do { - - if (pos < end) - buffer[pos] = (a % 10) + '0'; - pos--; - a /= 10; - } while (a != 0); - if (neg) - if (pos < end) - buffer[pos] = '-'; -} - /* - * Since perror() is not allowed to change the contents of strerror()'s - * static buffer, both functions supply their own buffers to the - * internal function __strerror(). + * __strerror() has been deprecated in favor of strerror_r() + * and is provided for source compatibility only. */ - char * __strerror(int num, char *buf) { -#define UPREFIX "Unknown error: " - int len; -#ifdef NLS - int save_errno; - nl_catd catd; - - catd = catopen("libc", 0); -#endif - - if (num >= 0 && num < sys_nerr) { -#ifdef NLS - strlcpy(buf, catgets(catd, 1, num, - (char *)sys_errlist[num]), NL_TEXTMAX); -#else - return(sys_errlist[num]); -#endif - } else { -#ifdef NLS - len = strlcpy(buf, catgets(catd, 1, 0xffff, UPREFIX), NL_TEXTMAX); -#else - len = strlcpy(buf, UPREFIX, NL_TEXTMAX); -#endif - __itoa(num, buf, len, NL_TEXTMAX); - errno = EINVAL; - } - -#ifdef NLS - save_errno = errno; - catclose(catd); - errno = save_errno; -#endif - - return buf; + (void)strerror_r(num, buf, NL_TEXTMAX); + return (buf); } diff --git a/lib/libc/string/strerror.c b/lib/libc/string/strerror.c index 6496f50afdd..edb6af73864 100644 --- a/lib/libc/string/strerror.c +++ b/lib/libc/string/strerror.c @@ -28,23 +28,17 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strerror.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $"; +static char *rcsid = "$OpenBSD: strerror.c,v 1.6 2004/05/03 05:07:34 espie Exp $"; #endif /* LIBC_SCCS and not lint */ #include <string.h> #include <limits.h> -/* - * Since perror() is not allowed to change the contents of strerror()'s - * static buffer, both functions supply their own buffers to the - * internal function __strerror(). - */ - -extern char *__strerror(int, char *); - char * strerror(int num) { static char buf[NL_TEXTMAX]; - return __strerror(num, buf); + + (void)strerror_r(num, buf, sizeof(buf)); + return (buf); } diff --git a/lib/libc/string/strerror_r.c b/lib/libc/string/strerror_r.c index aab6db5303c..db264bcf505 100644 --- a/lib/libc/string/strerror_r.c +++ b/lib/libc/string/strerror_r.c @@ -1,30 +1,120 @@ -/* $OpenBSD: strerror_r.c,v 1.1 2002/11/21 20:45:05 marc Exp $ */ +/* $OpenBSD: strerror_r.c,v 1.2 2004/05/03 05:07:34 espie Exp $ */ /* Public Domain <marc@snafu.org> */ #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strerror_r.c,v 1.1 2002/11/21 20:45:05 marc Exp $"; +static char *rcsid = "$OpenBSD: strerror_r.c,v 1.2 2004/05/03 05:07:34 espie Exp $"; #endif /* LIBC_SCCS and not lint */ +#ifdef NLS +#define catclose _catclose +#define catgets _catgets +#define catopen _catopen +#include <nl_types.h> +#endif + +#define sys_errlist _sys_errlist +#define sys_nerr _sys_nerr + #include <errno.h> #include <limits.h> #include <string.h> -extern char *__strerror(int, char *); +static size_t +__digits10(unsigned int num) +{ + size_t i = 0; + + do { + num /= 10; + i++; + } while (num != 0); + + return i; +} + +static void +__itoa(int num, char *buffer, size_t start, size_t end) +{ + size_t pos; + unsigned int a; + int neg; + + if (num < 0) { + a = -num; + neg = 1; + } + else { + a = num; + neg = 0; + } + + pos = start + __digits10(a); + if (neg) + pos++; + + if (pos < end) + buffer[pos] = '\0'; + else { + if (end) + buffer[--end] = '\0'; /* XXX */ + } + pos--; + do { + + if (pos < end) + buffer[pos] = (a % 10) + '0'; + pos--; + a /= 10; + } while (a != 0); + if (neg) + if (pos < end) + buffer[pos] = '-'; +} + + +#define UPREFIX "Unknown error: " int strerror_r(int errnum, char *strerrbuf, size_t buflen) { int save_errno; int ret_errno; - char buf[NL_TEXTMAX]; + size_t len; +#ifdef NLS + nl_catd catd; +#endif save_errno = errno; - errno = 0; - __strerror(errnum, buf); - if (strlcpy(strerrbuf, buf, buflen) >= buflen) - errno = ERANGE; - ret_errno = errno; - errno = save_errno; + ret_errno = 0; + +#ifdef NLS + catd = catopen("libc", 0); +#endif + + if (errnum >= 0 && errnum < sys_nerr) { +#ifdef NLS + len = strlcpy(strerrbuf, catgets(catd, 1, errnum, + (char *)sys_errlist[errnum]), buflen); +#else + len = strlcpy(strerrbuf, sys_errlist[errnum], buflen); +#endif + if (len >= buflen) + ret_errno = ERANGE; + } else { +#ifdef NLS + len = strlcpy(strerrbuf, catgets(catd, 1, 0xffff, UPREFIX), + buflen); +#else + len = strlcpy(strerrbuf, UPREFIX, buflen); +#endif + __itoa(errnum, strerrbuf, len, buflen); + ret_errno = EINVAL; + } + +#ifdef NLS + catclose(catd); +#endif + errno = ret_errno ? ret_errno : save_errno; return (ret_errno); } |