From 7c10a76dec8afaf548bf14453ebd689e3457518e Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 10 Feb 2011 16:48:18 +0000 Subject: strerror_r: provide POSIX implementation * libc/include/string.h (strerror_r): Update declaration. * libc/string/strerror.c (strerror): Update documentation. * libc/string/strerror_r.c (strerror_r): Always return NUL-terminated string; don't overwrite too-short buf. * libc/string/xpg_strerror_r.c (__xpg_strerror_r): Implement POSIX variant. * libc/string/Makefile.am (GENERAL_SOURCES): Build new file. * libc/string/Makefile.in: Regenerate. --- newlib/libc/string/strerror_r.c | 46 ++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 8 deletions(-) (limited to 'newlib/libc/string/strerror_r.c') diff --git a/newlib/libc/string/strerror_r.c b/newlib/libc/string/strerror_r.c index be5358f3e..c2057b7f0 100644 --- a/newlib/libc/string/strerror_r.c +++ b/newlib/libc/string/strerror_r.c @@ -1,3 +1,4 @@ +/* GNU variant of strerror_r. */ /* FUNCTION <>---convert error number to string and copy to buffer @@ -7,7 +8,11 @@ INDEX ANSI_SYNOPSIS #include + #ifdef _GNU_SOURCE char *strerror_r(int <[errnum]>, char *<[buffer]>, size_t <[n]>); + #else + int strerror_r(int <[errnum]>, char *<[buffer]>, size_t <[n]>); + #endif TRAD_SYNOPSIS #include @@ -19,35 +24,60 @@ TRAD_SYNOPSIS DESCRIPTION <> converts the error number <[errnum]> into a string and copies the result into the supplied <[buffer]> for -a length up to <[n]>, including the NUL terminator. The value of -<[errnum]> is usually a copy of <>. If <> is not a known +a length up to <[n]>, including the NUL terminator. The value of +<[errnum]> is usually a copy of <>. If <> is not a known error number, the result is the empty string. See <> for how strings are mapped to <>. RETURNS -This function returns a pointer to a string. Your application must -not modify that string. +There are two variants: the GNU version always returns a NUL-terminated +string, which is <[buffer]> if all went well, but which is another +pointer if <[n]> was too small (leaving <[buffer]> untouched). If the +return is not <[buffer]>, your application must not modify that string. +The POSIX version returns 0 on success, <[EINVAL]> if <> was not +recognized, and <[ERANGE]> if <[n]> was too small. The variant chosen +depends on macros that you define before inclusion of <>. PORTABILITY -<> is a GNU extension. +<> with a <[char *]> result is a GNU extension. +<> with an <[int]> result is required by POSIX 2001. +This function is compliant only if <<_user_strerror>> is not provided, +or if it is thread-safe and does not modify <>. + +POSIX states that the contents of <[buf]> are unspecified on error, +although this implementation guarantees a NUL-terminated string for +all except <[n]> of 0. + +POSIX recommends that unknown <[errnum]> result in a message including +that value, however it is not a requirement and this implementation +provides only an empty string (unless you provide <<_user_strerror>>). +POSIX also recommends that unknown <[errnum]> fail with EINVAL even +when providing such a message, however it is not a requirement and +this implementation will return success if <<_user_strerror>> provided +a non-empty alternate string. <> requires no supporting OS subroutines. */ #undef __STRICT_ANSI__ +#define _GNU_SOURCE #include #include +#undef strerror_r +/* For backwards-compatible linking, this must be the GNU signature; + see xpg_strerror_r.c for the POSIX version. */ char * _DEFUN (strerror_r, (errnum, buffer, n), int errnum _AND char *buffer _AND size_t n) { - char *error; - error = strerror (errnum); + char *error = strerror (errnum); - return strncpy (buffer, (const char *)error, n); + if (strlen (error) >= n) + return error; + return strcpy (buffer, error); } -- cgit v1.2.3