Our strerror_r is lousy (it doesn't even match glibc's behavior); see my request to the newlib list. But even if newlib swaps over to a POSIX-compliant strerror_r, I argue that for Linux compatibility (not to mention backwards compatibility with existing programs), we need to continue to provide strerror_r with the glibc signature (and I will make sure of that when writing the newlib patch to whatever the consensus is there).
Meanwhile, gnulib really wants to use the POSIX interface; on glibc systems, it uses the __xpg_strerror_r interface (undeclared, but that's what you get with a leading double-underscore interface), when _POSIX_C_VERSION is high enough and _GNU_SOURCE is not in effect. Since __xpg_strerror_r is undeclared, we don't have to care about tweaking newlib's string.h for this patch (gnulib does a link-test probe for its existence). 2011-02-05 Eric Blake <ebl...@redhat.com> * errno.cc (__xpg_strerror_r): New function. * cygwin.din: Export it. * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump. -- Eric Blake ebl...@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index 2e7e647..780179a 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -1933,6 +1933,7 @@ xdrrec_skiprecord SIGFE __xdrrec_getrec SIGFE __xdrrec_setnonblock SIGFE xdrstdio_create SIGFE +__xpg_strerror_r SIGFE y0 NOSIGFE y0f NOSIGFE y1 NOSIGFE diff --git a/winsup/cygwin/errno.cc b/winsup/cygwin/errno.cc index a9860f4..91c381f 100644 --- a/winsup/cygwin/errno.cc +++ b/winsup/cygwin/errno.cc @@ -368,16 +368,23 @@ strerror (int errnum) return errstr; } -#if 0 +/* Newlib provides the glibc strerror_r interface, but like Linux, we + also provide the POSIX interface. POSIX leaves a lot of leeway, + but recommends that buf always be populated, and that both EINVAL + and ERANGE be returned when appropriate. */ extern "C" int -strerror_r (int errnum, char *buf, size_t n) +__xpg_strerror_r (int errnum, char *buf, size_t n) { char *errstr = strerror_worker (errnum); + int result = 0; if (!errstr) - return EINVAL; + { + __small_sprintf (errstr = _my_tls.locals.strerror_buf, + "Unknown error %u", (unsigned) errnum); + result = EINVAL; + } + strncpy (buf, errstr, n); if (strlen (errstr) >= n) - return ERANGE; - strcpy (buf, errstr); - return 0; + result = ERANGE; + return result; } -#endif diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index c757827..7246e8e 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -399,12 +399,13 @@ details. */ 233: Add TIOCGPGRP, TIOCSPGRP. Export llround, llroundf. 234: Export program_invocation_name, program_invocation_short_name. 235: Export madvise. + 236: Export __xpg_strerror_r. */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 235 +#define CYGWIN_VERSION_API_MINOR 236 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible
signature.asc
Description: OpenPGP digital signature