From 6ba832b158c91c6b35e1832220b3fc5ebf76333f Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Mon, 17 Jun 2002 19:49:02 +0000 Subject: Implement strerror_r. This is per SuSv3, not glibc which does something different. -Erik --- include/string.h | 2 +- libc/string/strerror.c | 57 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/include/string.h b/include/string.h index 22608b660..6149955ef 100644 --- a/include/string.h +++ b/include/string.h @@ -235,7 +235,7 @@ extern char *strerror (int __errnum) __THROW; #ifdef __USE_MISC /* Reentrant version of `strerror'. If a temporary buffer is required, at most BUFLEN bytes of BUF will be used. */ -extern char *strerror_r (int __errnum, char *__buf, size_t __buflen) __THROW; +extern int strerror_r (int __errnum, char *__buf, size_t buflen) __THROW; #endif /* We define this function always since `bzero' is sometimes needed when diff --git a/libc/string/strerror.c b/libc/string/strerror.c index 890a03d1a..80f82de25 100644 --- a/libc/string/strerror.c +++ b/libc/string/strerror.c @@ -32,6 +32,11 @@ Cambridge, MA 02139, USA. */ * Manuel Novoa III Feb 2002 * * Change to _int10tostr and fix a bug in end-of-buf arg. + * + * Erik Andersen June 2002 + * + * Added strerror_r (per SuSv3 which differs from glibc) and adapted + * strerror to match. */ #define WANT_ERRORLIST 1 @@ -41,35 +46,51 @@ Cambridge, MA 02139, USA. */ #include #include +int strerror_r(int err, char *retbuf, size_t buflen) +{ #if WANT_ERRORLIST -static char retbuf[48]; + if (err < 0 || err >= sys_nerr || sys_errlist[err] == NULL) { + return -EINVAL; + } + if (retbuf==NULL || buflen < 1) { + return -ERANGE; + } + strncpy(retbuf, sys_errlist[err], buflen); + retbuf[buflen-1] = '\0'; + return 0; #else -#if __BUFLEN_INT10TOSTR > 12 -#error currently set up for 32 bit ints max! -#endif -static char retbuf[33]; /* 33 is sufficient for 32 bit ints */ + char *pos; + static const char unknown_error[] = "Unknown Error: errno"; /* = */ + + if (err < 0 || err >= sys_nerr || sys_errlist[err] == NULL) { + return -EINVAL; + } + /* unknown error -- leave space for the '=' */ + pos = _int10tostr(retbuf+sizeof(retbuf)-1, err) - sizeof(unknown_error); + strcpy(pos, unknown_error); + *(pos + sizeof(unknown_error) - 1) = '='; + return 0; #endif -static const char unknown_error[] = "Unknown Error: errno"; /* = */ +} /* Return a string descibing the errno code in ERRNUM. The storage is good only until the next call to strerror. Writing to the storage causes undefined behavior. */ char *strerror(int err) { - char *pos; - #if WANT_ERRORLIST - if ((err >= 0) && (err < sys_nerr)) { - strcpy(retbuf, sys_errlist[err]); - return retbuf; - } + static char retbuf[48]; +#else +#if __BUFLEN_INT10TOSTR > 12 +#error currently set up for 32 bit ints max! #endif - - /* unknown error -- leave space for the '=' */ - pos = _int10tostr(retbuf+sizeof(retbuf)-1, err) - sizeof(unknown_error); - strcpy(pos, unknown_error); - *(pos + sizeof(unknown_error) - 1) = '='; - return pos; + static char retbuf[33]; /* 33 is sufficient for 32 bit ints */ +#endif + + if (strerror_r(err, retbuf, sizeof(retbuf)) != 0) { + return NULL; + } + return(retbuf); } #ifdef CHECK_BUF -- cgit v1.2.3