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