diff options
author | Eric Blake <eblake@redhat.com> | 2011-05-25 22:47:32 +0400 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2011-05-25 22:47:32 +0400 |
commit | 154fa4d7ef23ee85e937ab6d1f1fab49dfb1872a (patch) | |
tree | 37f8255306d8a95e2cddf0f3b72045756b7cc487 /winsup/cygwin/errno.cc | |
parent | 4805b60ccfeee32a4ac3547e680c917f9e5c1d39 (diff) |
perror: fix POSIX compliance and work with recent newlib change
* 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.
Diffstat (limited to 'winsup/cygwin/errno.cc')
-rw-r--r-- | winsup/cygwin/errno.cc | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/winsup/cygwin/errno.cc b/winsup/cygwin/errno.cc index aa311b7e2..f3b925ef2 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 |