diff options
author | Eric Blake <eblake@redhat.com> | 2011-05-21 10:08:28 -0600 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2011-05-21 10:14:37 -0600 |
commit | 2f0357585d836b7349192ea4276b78adfd551cbc (patch) | |
tree | 6e85abc031d1a058c4c53db21c65216aef7ed87a /lib/strerror_r.c | |
parent | f56bca9f1091b3e6b3cf259d3a9f6c0859998a1c (diff) | |
download | gnulib-2f0357585d836b7349192ea4276b78adfd551cbc.tar.gz |
strerror_r: avoid clobbering strerror on cygwin
Avoid cygwin strerror_r, since it clobbers strerror buffer through
cygwin 1.7.9. __xpg_strerror_r is okay, but if a program is
compiled on cygwin 1.7.8 or earlier, it is not available.
* lib/strerror_r.c (strerror_r): Don't use cygwin's strerror_r;
fall back instead to sys_errlist.
* modules/strerror (configure.ac): Add witness.
* tests/test-strerror_r.c (main): Enhance test.
* doc/posix-functions/strerror_r.texi (strerror_r): Document it.
* tests/test-perror2.c (main): Free memory before exit.
Signed-off-by: Eric Blake <eblake@redhat.com>
Diffstat (limited to 'lib/strerror_r.c')
-rw-r--r-- | lib/strerror_r.c | 47 |
1 files changed, 10 insertions, 37 deletions
diff --git a/lib/strerror_r.c b/lib/strerror_r.c index 2144fc652e..65d230ac5b 100644 --- a/lib/strerror_r.c +++ b/lib/strerror_r.c @@ -38,7 +38,7 @@ # define USE_XPG_STRERROR_R 1 -#elif HAVE_DECL_STRERROR_R && !(__GLIBC__ >= 2 || defined __UCLIBC__) +#elif HAVE_DECL_STRERROR_R && !(__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__) /* The system's strerror_r function is OK, except that its third argument is 'int', not 'size_t', or its return type is wrong. */ @@ -47,14 +47,16 @@ # define USE_SYSTEM_STRERROR_R 1 -#else /* (__GLIBC__ >= 2 || defined __UCLIBC__ ? !HAVE___XPG_STRERROR_R : !HAVE_DECL_STRERROR_R) */ +#else /* (__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__ ? !HAVE___XPG_STRERROR_R : !HAVE_DECL_STRERROR_R) */ -/* Use the system's strerror(). */ +/* Use the system's strerror(). Exclude glibc and cygwin because the + system strerror_r has the wrong return type, and cygwin 1.7.9 + strerror_r clobbers strerror. */ # undef strerror # define USE_SYSTEM_STRERROR 1 -# if defined __NetBSD__ || defined __hpux || ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __sgi || (defined __sun && !defined _LP64) +# if defined __NetBSD__ || defined __hpux || ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __sgi || (defined __sun && !defined _LP64) || defined __CYGWIN__ /* No locking needed. */ @@ -75,7 +77,7 @@ extern char *sys_errlist[]; extern int sys_nerr; # endif -/* Get sys_nerr, sys_errlist on native Windows. */ +/* Get sys_nerr, sys_errlist on native Windows and Cygwin. */ # include <stdlib.h> # else @@ -467,36 +469,6 @@ strerror_r (int errnum, char *buf, size_t buflen) else ret = strerror_r (errnum, buf, buflen); } -# elif defined __CYGWIN__ - /* Cygwin <= 1.7.7 only provides the glibc interface, is thread-safe, and - always succeeds (although it may truncate). In Cygwin >= 1.7.8, for - valid errnum values, instead of truncating, it leaves the buffer - untouched. */ - { - char stackbuf[256]; - - if (buflen < sizeof (stackbuf)) - { - size_t len; - - stackbuf[0] = '\0'; /* in case strerror_r does nothing */ - strerror_r (errnum, stackbuf, sizeof (stackbuf)); - len = strlen (stackbuf); - if (len < buflen) - { - memcpy (buf, stackbuf, len + 1); - ret = 0; - } - else - ret = ERANGE; - } - else - { - buf[0] = '\0'; /* in case strerror_r does nothing */ - strerror_r (errnum, buf, buflen); - ret = 0; - } - } # else ret = strerror_r (errnum, buf, buflen); # endif @@ -526,12 +498,13 @@ strerror_r (int errnum, char *buf, size_t buflen) /* Try to do what strerror (errnum) does, but without clobbering the buffer used by strerror(). */ -# if defined __NetBSD__ || defined __hpux || ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) /* NetBSD, HP-UX, native Win32 */ +# if defined __NetBSD__ || defined __hpux || ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __CYGWIN__ /* NetBSD, HP-UX, native Win32, Cygwin */ /* NetBSD: sys_nerr, sys_errlist are declared through _NETBSD_SOURCE and <errno.h> above. HP-UX: sys_nerr, sys_errlist are declared explicitly above. - native Win32: sys_nerr, sys_errlist are declared in <stdlib.h>. */ + native Win32: sys_nerr, sys_errlist are declared in <stdlib.h>. + Cygwin: sys_nerr, sys_errlist are declared in <stdlib.h>. */ if (errnum >= 0 && errnum < sys_nerr) { # if HAVE_CATGETS && (defined __NetBSD__ || defined __hpux) |