provide __xpg_strerror_r

2011-02-05 Thread Eric Blake
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  

* 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


Re: provide __xpg_strerror_r

2011-02-05 Thread Christopher Faylor
On Sat, Feb 05, 2011 at 01:04:16PM -0700, Eric Blake wrote:
>Our strerror_r is lousy (it doesn't even match glibc's behavior); see my
>request to the newlib list.

We really should just implement strerror_r in errno.cc.  It doesn't make
sense to have two different implementations

cgf


Re: provide __xpg_strerror_r

2011-02-05 Thread Eric Blake
On 02/05/2011 01:28 PM, Christopher Faylor wrote:
> On Sat, Feb 05, 2011 at 01:04:16PM -0700, Eric Blake wrote:
>> Our strerror_r is lousy (it doesn't even match glibc's behavior); see my
>> request to the newlib list.
> 
> We really should just implement strerror_r in errno.cc.  It doesn't make
> sense to have two different implementations

You mean, implement the POSIX interface for strerror_r in errno.cc, and
ditch glibc compatibility?  But, backwards compatibility demands that we
have two interfaces - the glibc one that returns char* for satisfying
the link demands of existing applications, and the POSIX one that
returns int, so we really are stuck with providing two forms of
strerror_r if we intend to comply with POSIX.

We already provide our own strerror() (it provides a better experience
for out-of-range values that the newlib interface), but we're currently
using the newlib strerror_r() (in spite of its truncation flaw).

How should I rework this patch?

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature