Hi Eric,
> in the process of adding
> __xpg_sterror_r, the original strerror_r was fixed to align more closely
> to glibc behavior. Thus, it was changed so that strerror_r(EACCES, buf,
> 2) no longer overwrites buf with a (truncated) message to buf, so the
> caller instead has to manually copy the static string result over to buf.
>
> When testing at commit d118714, I got:
>
> ../../gltests/test-strerror_r.c:82: assertion failed
> /bin/sh: line 5: 2060 Aborted (core dumped)
> EXEEXT='.exe' srcdir='../../gltests' MAKE='make' ${dir}$tst
> FAIL: test-strerror_r.exe
>
> at that point, line 82 was:
>
> 82 ASSERT ((strcmp (buf, "BADFACE") == 0) == (i == 0));
>
> with i at 1.
Thanks for explaining. But that means that a binary built with Cygwin
1.7.5 will still fail when run on Cygwin >= 1.7.9. The complete fix
ought to look something like this, I guess?
2011-05-19 Bruno Haible <[email protected]>
strerror_r: Work around strerror_r() change in Cygwin 1.7.9.
* lib/strerror_r.c (strerror_r) [CYGWIN]: Recognize when the system's
strerror_r() returned without filling the buffer.
Reported by Eric Blake.
--- lib/strerror_r.c.orig Thu May 19 22:48:15 2011
+++ lib/strerror_r.c Thu May 19 22:48:05 2011
@@ -456,10 +456,34 @@
ret = strerror_r (errnum, buf, buflen);
}
# elif defined __CYGWIN__
- /* Cygwin 1.7.8 only provides the glibc interface, is thread-safe, and
- always succeeds (although it may truncate). */
- strerror_r (errnum, buf, buflen);
- ret = 0;
+ /* Cygwin <= 1.7.8 only provides the glibc interface, is thread-safe, and
+ always succeeds (although it may truncate). In Cygwin >= 1.7.9, 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
--
In memoriam Anne Boleyn <http://en.wikipedia.org/wiki/Anne_Boleyn>