fix perror POSIX compliance
Eric Blake
eblake@redhat.com
Mon May 23 23:28:00 GMT 2011
This depends on the newlib patch:
http://sourceware.org/ml/newlib/2011/msg00215.html
In fact, if that patch goes in, then this one is required to avoid a
link failure; this one can probably go in first but makes no difference
to perror without the newlib patch.
winsup/cygwin/ChangeLog | 6 +++
winsup/cygwin/cygtls.h | 1 +
winsup/cygwin/errno.cc | 43 ++++++++++++++++-------
winsup/cygwin/tlsoffsets.h | 82
++++++++++++++++++++++----------------------
4 files changed, 78 insertions(+), 54 deletions(-)
2011-05-23 Eric Blake <eblake@redhat.com>
* cygtls.h (strerror_r_buf): New buffer.
* errno.cc (strerror): Move guts...
(_strerror_r): ...to new function demanded by newlib.
(strerror_r): Don't clobber strerror buffer.
(_user_strerror): Drop unused declaration.
* tlsoffsets.h: Regenerate.
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index 6359e7c..a1642b1 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -110,6 +110,7 @@ struct _local_storage
/* strerror errno.cc */
char strerror_buf[sizeof ("Unknown error -2147483648")];
+ char strerror_r_buf[sizeof ("Unknown error -2147483648")];
/* times.cc */
char timezone_buf[20];
diff --git a/winsup/cygwin/errno.cc b/winsup/cygwin/errno.cc
index aa311b7..f3b925e 100644
--- a/winsup/cygwin/errno.cc
+++ b/winsup/cygwin/errno.cc
@@ -360,8 +360,6 @@ seterrno (const char *file, int line)
seterrno_from_win_error (file, line, GetLastError ());
}
-extern char *_user_strerror _PARAMS ((int));
-
static char *
strerror_worker (int errnum)
{
@@ -373,22 +371,38 @@ strerror_worker (int errnum)
return res;
}
-/* strerror: convert from errno values to error strings. Newlib's
- strerror_r returns "" for unknown values, so we override it to
- provide a nicer thread-safe result string and set errno. */
+/* Newlib requires this override for perror and friends to avoid
+ clobbering strerror() buffer, without having to differentiate
+ between strerror_r signatures. This function is intentionally not
+ exported, so that only newlib can use it. */
extern "C" char *
-strerror (int errnum)
+_strerror_r (struct _reent *, int errnum, int internal, int *errptr)
{
char *errstr = strerror_worker (errnum);
if (!errstr)
{
- __small_sprintf (errstr = _my_tls.locals.strerror_buf, "Unknown
error %d",
- errnum);
- errno = _impure_ptr->_errno = EINVAL;
+ errstr = internal ? _my_tls.locals.strerror_r_buf
+ : _my_tls.locals.strerror_buf;
+ __small_sprintf (errstr, "Unknown error %d", errnum);
+ if (errptr)
+ *errptr = EINVAL;
}
return errstr;
}
+/* strerror: convert from errno values to error strings. Newlib's
+ strerror_r returns "" for unknown values, so we override it to
+ provide a nicer thread-safe result string and set errno. */
+extern "C" char *
+strerror (int errnum)
+{
+ int error = 0;
+ char *result = _strerror_r (NULL, errnum, 0, &error);
+ if (error)
+ set_errno (error);
+ return result;
+}
+
/* Newlib's <string.h> provides declarations for two strerror_r
variants, according to preprocessor feature macros. However, it
returns "" instead of "Unknown error ...", so we override both
@@ -396,10 +410,13 @@ strerror (int errnum)
extern "C" char *
strerror_r (int errnum, char *buf, size_t n)
{
- char *error = strerror (errnum);
- if (strlen (error) >= n)
- return error;
- return strcpy (buf, error);
+ int error = 0;
+ char *errstr = _strerror_r (NULL, errnum, 1, &error);
+ if (error)
+ set_errno (error);
+ if (strlen (errstr) >= n)
+ return errstr;
+ return strcpy (buf, errstr);
}
extern "C" int
diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h
index 4e459df..3ef7963 100644
--- a/winsup/cygwin/tlsoffsets.h
+++ b/winsup/cygwin/tlsoffsets.h
@@ -1,6 +1,6 @@
//;# autogenerated: Do not edit.
-//; $tls::sizeof__cygtls = 3984;
+//; $tls::sizeof__cygtls = 4012;
... // rest of generated file patch elided
--
Eric Blake eblake@redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 619 bytes
Desc: OpenPGP digital signature
URL: <http://cygwin.com/pipermail/cygwin-patches/attachments/20110523/d4265264/attachment.sig>
More information about the Cygwin-patches
mailing list