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