From 5b0c2c6d870cc9f9f2eae32f4d71abc6f9348e20 Mon Sep 17 00:00:00 2001 From: Manuel Novoa III Date: Tue, 18 Jun 2002 08:41:28 +0000 Subject: Fix perror() and printf("%m") to not call strerror(), as required by the standards. Temporarily added a utility function to wrap Erik's strerror_r so that "Unknown error xxx" strings can be generated for errno's which cause strerror_r to fail. That utility function will eventually be merged in with the strerror/strerror_r functions when I change over to optionallly mmap'ing the system error strings to provide for lower mem comsumption on non-MMU platforms, as well as locale-specific system error messages. --- libc/stdio/stdio.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) (limited to 'libc/stdio/stdio.c') diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c index 1462874f0..c84731675 100644 --- a/libc/stdio/stdio.c +++ b/libc/stdio/stdio.c @@ -3105,14 +3105,22 @@ void perror(register const char *s) #ifdef __STDIO_PRINTF_M_SPEC fprintf(_stderr, "%s%s%m\n", s, sep); /* Use the gnu %m feature. */ #else - /* TODO: use strerror_r instead? */ - fprintf(_stderr, "%s%s%s\n", s, sep, strerror(errno)); + { + char buf[64]; + fprintf(_stderr, "%s%s%s\n", s, sep, + _stdio_strerror_r(errno, buf, sizeof(buf))); + } #endif #else /* Note: Assumes stderr not closed or buffered. */ - __STDIO_THREADLOCK(stderr); - _stdio_fdout(STDERR_FILENO, s, sep, strerror(errno)); - __STDIO_THREADUNLOCK(stderr); + { + char buf[64]; + + __STDIO_THREADLOCK(stderr); + _stdio_fdout(STDERR_FILENO, s, sep, + _stdio_strerror_r(errno, buf, sizeof(buf))); + __STDIO_THREADUNLOCK(stderr); + } #endif } @@ -3209,3 +3217,38 @@ char *_uintmaxtostr(char * __restrict bufend, uintmax_t uval, #undef INTERNAL_DIV_MOD #endif +/**********************************************************************/ +#ifdef L__stdio_strerror_r + +/* This is an internal routine, and assumes buf and buflen are set + * appropriately. + * + * WARNING!!! While it is similar to the glibc strerror_r function, + * it is not the same. It is expected that "unknown" error strings + * will fit in the buffer passed. Also, the return value may not + * be == buf, as unknown strings are "right-justified" in the buf + * due to the way _int10stostr works. */ + +static const char unknown[] = "Unknown error"; + +char *_stdio_strerror_r(int err, char *buf, size_t buflen) +{ + int errsave; + + assert(buflen >= __UIM_BUFLEN_INT + sizeof(unknown)); + + errsave = errno; /* Backup the errno. */ + + if (strerror_r(err, buf, buflen)) { /* Failed! */ + __set_errno(errsave); /* Restore old errno. */ + + buf = _int10tostr(buf+buflen-1, err) - sizeof(unknown); + strcpy(buf, unknown); + buf[sizeof(unknown)-1] = ' '; /* Overwrite the nul. */ + } + + return buf; +} + +#endif +/**********************************************************************/ -- cgit v1.2.3