summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-06-17 19:49:02 +0000
committerEric Andersen <andersen@codepoet.org>2002-06-17 19:49:02 +0000
commit6ba832b158c91c6b35e1832220b3fc5ebf76333f (patch)
treeda543c5d45af47e6b50358db49dfcd12af62663c
parente53425a64572ee32e71eb4e77ded3b6e813634bc (diff)
Implement strerror_r. This is per SuSv3, not glibc which does
something different. -Erik
-rw-r--r--include/string.h2
-rw-r--r--libc/string/strerror.c57
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 <string.h>
#include <errno.h>
+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