From ccbe143d523fdbdabe4b163df0ca0a75ef9f3b72 Mon Sep 17 00:00:00 2001 From: Zoltan Fridrich Date: Thu, 22 Jun 2023 13:43:23 +0200 Subject: [PATCH] Handle both XSI and GNU versions of strerror_r Signed-off-by: Zoltan Fridrich --- common/compat.c | 61 ++++++++++++++++++++++++------------------------ common/compat.h | 12 ++++------ common/debug.c | 2 +- common/message.c | 2 +- configure.ac | 20 +++++++++++++++- meson.build | 20 +++++++++++++++- 6 files changed, 74 insertions(+), 43 deletions(-) diff --git a/common/compat.c b/common/compat.c index 136527388..4e0c89c15 100644 --- a/common/compat.c +++ b/common/compat.c @@ -910,37 +910,6 @@ secure_getenv (const char *name) return getenv (name); } -#ifndef HAVE_STRERROR_R - -int -strerror_r (int errnum, - char *buf, - size_t buflen) -{ -#ifdef OS_WIN32 -#if _WIN32_WINNT < 0x502 /* WinXP or older */ - int n = sys_nerr; - const char *p; - if (errnum < 0 || errnum >= n) - p = sys_errlist[n]; - else - p = sys_errlist[errnum]; - if (buf == NULL || buflen == 0) - return EINVAL; - strncpy(buf, p, buflen); - buf[buflen-1] = 0; - return 0; -#else /* Server 2003 or newer */ - return strerror_s (buf, buflen, errnum); -#endif /*_WIN32_WINNT*/ - -#else - #error no strerror_r implementation -#endif -} - -#endif /* HAVE_STRERROR_R */ - #ifndef HAVE_ISATTY int @@ -1037,6 +1006,36 @@ fdwalk (int (* cb) (void *data, int fd), #endif /* OS_UNIX */ +void +p11_strerror_r (int errnum, + char *buf, + size_t buflen) +{ +#if defined(HAVE_XSI_STRERROR_R) + strerror_r (errnum, buf, buflen); +#elif defined(HAVE_GNU_STRERROR_R) + char *str = strerror_r (errnum, buf, buflen); + strncpy (buf, str, buflen); +#elif defined(OS_WIN32) +#if _WIN32_WINNT < 0x502 /* WinXP or older */ + int n = sys_nerr; + const char *p; + if (errnum < 0 || errnum >= n) + p = sys_errlist[n]; + else + p = sys_errlist[errnum]; + if (buf == NULL || buflen == 0) + return; + strncpy(buf, p, buflen); + buf[buflen - 1] = '\0'; +#else /* Server 2003 or newer */ + strerror_s (buf, buflen, errnum); +#endif /* _WIN32_WINNT */ +#else + #error no strerror_r implementation +#endif +} + int p11_ascii_tolower (int c) { diff --git a/common/compat.h b/common/compat.h index 08dd50629..643e7c8a4 100644 --- a/common/compat.h +++ b/common/compat.h @@ -364,14 +364,6 @@ unsigned long getauxval (unsigned long type); char * secure_getenv (const char *name); -#ifndef HAVE_STRERROR_R - -int strerror_r (int errnum, - char *buf, - size_t buflen); - -#endif /* HAVE_STRERROR_R */ - #ifndef HAVE_FDWALK int fdwalk (int (* cb) (void *data, int fd), @@ -402,6 +394,10 @@ int isatty (int fd); #endif +void p11_strerror_r (int errnum, + char *buf, + size_t buflen); + int p11_ascii_tolower (int c); int p11_ascii_toupper (int c); diff --git a/common/debug.c b/common/debug.c index 628fbcb86..9d12c8c49 100644 --- a/common/debug.c +++ b/common/debug.c @@ -165,7 +165,7 @@ p11_debug_message_err (int flag, if (p11_message_locale != (locale_t) 0) strncpy (strerr, strerror_l (errnum, p11_message_locale), sizeof (strerr)); #else - strerror_r (errnum, strerr, sizeof (strerr)); + p11_strerror_r (errnum, strerr, sizeof (strerr)); #endif strerr[P11_DEBUG_MESSAGE_MAX - 1] = 0; fprintf (stderr, ": %s\n", strerr); diff --git a/common/message.c b/common/message.c index e439def7a..92cd4bac1 100644 --- a/common/message.c +++ b/common/message.c @@ -123,7 +123,7 @@ p11_message_err (int errnum, if (p11_message_locale != (locale_t) 0) strncpy (strerr, strerror_l (errnum, p11_message_locale), sizeof (strerr)); #else - strerror_r (errnum, strerr, sizeof (strerr)); + p11_strerror_r (errnum, strerr, sizeof (strerr)); #endif strerr[P11_MESSAGE_MAX - 1] = 0; diff --git a/configure.ac b/configure.ac index 92e189b70..3e3b35307 100644 --- a/configure.ac +++ b/configure.ac @@ -134,7 +134,7 @@ if test "$os_unix" = "yes"; then AC_CHECK_MEMBERS([struct dirent.d_type],,,[#include ]) AC_CHECK_FUNCS([getprogname getexecname basename mkstemp mkdtemp]) AC_CHECK_FUNCS([getauxval getresuid secure_getenv]) - AC_CHECK_FUNCS([strnstr memdup strndup strerror_r]) + AC_CHECK_FUNCS([strnstr memdup strndup]) AC_CHECK_FUNCS([reallocarray]) AC_CHECK_DECLS([reallocarray], [], [], [[#include ]]) AC_CHECK_FUNCS([fdwalk]) @@ -144,6 +144,24 @@ if test "$os_unix" = "yes"; then AC_CHECK_FUNCS([issetugid]) AC_CHECK_FUNCS([isatty]) + AC_CHECK_FUNC( + [strerror_r], + [AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ + #include + #include + + int main (void) + { + char buf[32]; + return strerror_r (EINVAL, buf, 32); + } + ]])], + [AC_DEFINE([HAVE_XSI_STRERROR_R], 1, [Whether XSI-compliant strerror_r() is available])], + [AC_DEFINE([HAVE_GNU_STRERROR_R], 1, [Whether GNU-specific strerror_r() is available])], + [])], + []) + AC_CACHE_CHECK([for thread-local storage class], [ac_cv_tls_keyword], [ac_cv_tls_keyword= diff --git a/meson.build b/meson.build index 7b6e08c51..8e0f7da18 100644 --- a/meson.build +++ b/meson.build @@ -289,7 +289,6 @@ functions = [ 'reallocarray', 'secure_getenv', 'setenv', - 'strerror_r', 'strnstr', 'vasprintf' ] @@ -300,6 +299,25 @@ foreach f : functions endif endforeach +if cc.has_function('strerror_r', prefix: '#include ') + strerror_r_code = ''' +#include +#include + +int main (void) +{ + char buf[32]; + return strerror_r (EINVAL, buf, 32); +} +''' + strerror_r_check = cc.run(strerror_r_code, name : 'strerror_r check') + if strerror_r_check.returncode() == 0 + conf.set('HAVE_XSI_STRERROR_R', 1) + else + conf.set('HAVE_GNU_STRERROR_R', 1) + endif +endif + conf.set10('HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME', cc.has_header_symbol('errno.h', 'program_invocation_short_name',