Browse Source

Implement strerror_r. This is per SuSv3, not glibc which does
something different.
-Erik

Eric Andersen 22 years ago
parent
commit
6ba832b158
2 changed files with 40 additions and 19 deletions
  1. 1 1
      include/string.h
  2. 39 18
      libc/string/strerror.c

+ 1 - 1
include/string.h

@@ -235,7 +235,7 @@ extern char *strerror (int __errnum) __THROW;
 #ifdef	__USE_MISC
 #ifdef	__USE_MISC
 /* Reentrant version of `strerror'.  If a temporary buffer is required, at
 /* Reentrant version of `strerror'.  If a temporary buffer is required, at
    most BUFLEN bytes of BUF will be used.  */
    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
 #endif
 
 
 /* We define this function always since `bzero' is sometimes needed when
 /* We define this function always since `bzero' is sometimes needed when

+ 39 - 18
libc/string/strerror.c

@@ -32,6 +32,11 @@ Cambridge, MA 02139, USA.  */
  * Manuel Novoa III       Feb 2002
  * Manuel Novoa III       Feb 2002
  *
  *
  * Change to _int10tostr and fix a bug in end-of-buf arg.
  * 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
 #define WANT_ERRORLIST     1
@@ -41,35 +46,51 @@ Cambridge, MA 02139, USA.  */
 #include <string.h>
 #include <string.h>
 #include <errno.h>
 #include <errno.h>
 
 
+int strerror_r(int err, char *retbuf, size_t buflen)
+{
 #if WANT_ERRORLIST
 #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
 #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
 #endif
-static const char unknown_error[] = "Unknown Error: errno"; /* = */
+}
 
 
 /* Return a string descibing the errno code in ERRNUM.
 /* Return a string descibing the errno code in ERRNUM.
    The storage is good only until the next call to strerror.
    The storage is good only until the next call to strerror.
    Writing to the storage causes undefined behavior.  */
    Writing to the storage causes undefined behavior.  */
 char *strerror(int err)
 char *strerror(int err)
 {
 {
-	char *pos;
-
 #if WANT_ERRORLIST
 #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
 #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
 #ifdef CHECK_BUF