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

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to