summaryrefslogtreecommitdiff
path: root/libc/string/strerror.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/string/strerror.c')
-rw-r--r--libc/string/strerror.c61
1 files changed, 50 insertions, 11 deletions
diff --git a/libc/string/strerror.c b/libc/string/strerror.c
index 91565965f..3aa8b57e2 100644
--- a/libc/string/strerror.c
+++ b/libc/string/strerror.c
@@ -16,31 +16,70 @@ License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
+/*
+ * Manuel Novoa III Dec 2000
+ *
+ * Converted to use my new (un)signed long (long) to string routines, which
+ * are smaller than the previous functions and don't require static buffers.
+ * Removed dependence on strcat in the process.
+ *
+ * Also appended a test routine ( -DSTRERROR_TEST ) to allow a quick check
+ * on the buffer length when the sys_errorlist is modified.
+ */
+
#include <stdio.h>
#include <string.h>
#include <errno.h>
+#include <limits.h>
+
+#if (INT_MAX >> 31)
+/* We're set up for 32 bit ints */
+#error need to check size allocation for static buffer 'retbuf'
+#endif
-extern char *itoa(int);
+extern char *__ltostr(char *buf, long uval, int base, int uppercase);
+
+static char retbuf[33]; /* 33 is sufficient for 32 bit ints */
+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)
{
- static char retbuf[80];
+ char *pos;
- if (sys_nerr) {
- if (err < 0 || err >= sys_nerr)
- goto unknown;
+ if ((err >= 0) && (err < sys_nerr)) {
strcpy(retbuf, sys_errlist[err]);
return retbuf;
}
- if (err <= 0)
- goto unknown;
+ /* unknown error */
+ pos = __ltostr(retbuf + sizeof(retbuf) + 1, err, 10, 0)
+ - sizeof(unknown_error); /* leave space for the '=' */
+ strcpy(pos, unknown_error);
+ *(pos + sizeof(unknown_error) - 1) = '=';
+ return pos;
+}
+
+#if STRERROR_TEST
+/* quick way to check for sufficient buffer length */
+#include <stdio.h>
+#include <stdlib.h>
+int main(void)
+{
+ int max = 0;
+ int i, j;
+ char *p;
+ for ( i=0 ; i < sys_nerr ; i++ ) {
+ j = strlen(sys_errlist[i])+1;
+ if (j > max) max = j;
+ }
+ printf("max len = %i\n", j);
- unknown:
- strcpy(retbuf, "Unknown Error: errno=");
- strcat(retbuf, (char *) itoa(err));
- return retbuf;
+ p = strerror(INT_MIN);
+ printf("<%s> %d\n", p, strlen(p)+1);
+ printf("current buffer length is %d\n", sizeof(retbuf));
+ return EXIT_SUCCESS;
}
+#endif