diff options
author | Eric Andersen <andersen@codepoet.org> | 2000-12-20 22:52:58 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2000-12-20 22:52:58 +0000 |
commit | c6218dbae579de0cd20f5a7f1e9877673e28225d (patch) | |
tree | 0fc8aaf54189b8ef6a2d130c12539814e0a724ee /libc/string | |
parent | 97112ff6f4f2a1dcd4c7f8a7512e0a4a02a2a332 (diff) |
A number of updates from Manuel Novoa III. Things look good...
Diffstat (limited to 'libc/string')
-rw-r--r-- | libc/string/strerror.c | 61 | ||||
-rw-r--r-- | libc/string/strsignal.c | 75 |
2 files changed, 113 insertions, 23 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 diff --git a/libc/string/strsignal.c b/libc/string/strsignal.c index 4cadb144a..1a0a6ca47 100644 --- a/libc/string/strsignal.c +++ b/libc/string/strsignal.c @@ -4,11 +4,25 @@ * GNU Library General Public License. */ +/* + * 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 fixed a bug in the signal name lookup code. While the table is + * declared with dimension > 60, there are currently on 32 signals listed. + * + * Also appended a test routine ( -DSTRSIGNAL_TEST ) to allow a quick check + * on the buffer length when the sys_errorlist is modified. + */ + #include <string.h> #include <malloc.h> #include <signal.h> -extern char *itoa(int i); +extern char *__ltostr(char *buf, long uval, int base, int uppercase); const char *const sys_siglist[] = { "Unknown signal", @@ -46,26 +60,63 @@ const char *const sys_siglist[] = { NULL }; +#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 + /********************** Function strsignal ************************************/ char *strsignal(int sig) { - static char retbuf[80]; + static char retbuf[28]; /* 28 is sufficient for 32 bit ints */ + static const char unknown_signal[] = "Unknown Signal:"; + char *pos; - if (sys_siglist) { - if (sig < 0 || sig >= _NSIG) - goto unknown; + /* if ((sig >= 0) && (sig < _NSIG)) { */ + if ((sig >= 0) && (sig < 32)) { /* WARNING!!! NOT ALL _NSIG DEFINED!!! */ strcpy(retbuf, sys_siglist[sig]); return retbuf; } - if (sig <= 0) - goto unknown; - - unknown: - strcpy(retbuf, "Unknown Signal: "); - strcat(retbuf, (char *) itoa(sig)); - return retbuf; + pos = __ltostr(retbuf + sizeof(unknown_signal) + 1, sig, 10, 0) + - sizeof(unknown_signal); + strcpy(pos, unknown_signal); + *(pos + sizeof(unknown_signal) - 1) = ' '; + return pos; } /********************** THE END ********************************************/ + +#if STRSIGNAL_TEST +/* quick way to check for sufficient buffer length */ +#include <stdio.h> +#include <stdlib.h> +int main(void) +{ + int max = 0; + int i, j; + const char *p; + + printf("_NSIG = %d from headers\n", _NSIG); + for ( i=0 ; i < _NSIG ; i++ ) { + p = sys_siglist[i]; + if (!p) { + printf("Warning! I only count %d signals!\n", i); + break; + } + j = strlen(sys_siglist[i])+1; + if (j > max) max = j; + } + printf("max len = %i\n", j); + + p = strsignal(INT_MIN); + printf("<%s> %d\n", p, strlen(p)+1); + + p = strsignal(i-1); + printf("last signal %d is %s\n", i-1, p); + return EXIT_SUCCESS; +} +#endif |