diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2021-09-08 19:18:37 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2021-09-08 19:25:49 -0700 |
commit | d9559536909c5c8f819321cabc05f12652c7f9fd (patch) | |
tree | a9c298956c3a81cffcec848657f7f7ab0b74ff32 | |
parent | d99c9622d55cd37084af00843e1feffc0a71fc62 (diff) | |
download | gnulib-d9559536909c5c8f819321cabc05f12652c7f9fd.tar.gz |
strerror_r-posix: port even better to Android
* lib/strerror_r.c: Use STRERROR_R_CHAR_P to decide whether the
system strerror_r returns char *, and HAVE_DECL_STRERROR_R to
decide whether it either does that or returns an integer. In the
former case, use the system strerror_r even on platforms like
Android API level 23 that don’t have __xpg_strerror_r; also
check for strerror_r failure just in case.
* m4/error.m4 (gl_PREREQ_ERROR):
* m4/strerror_r.m4 (gl_PREREQ_STRERROR_R):
Use system extensions on Android, to avoid mishandling strerror_r
on API level 23 and later.
* modules/error, modules/strerror_r-posix (configure.ac):
Surround gl_PREREQ_ERROR with AS_IF instead of plain if, so that
AC_REQUIREs are propagated out.
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | lib/strerror_r.c | 35 | ||||
-rw-r--r-- | m4/error.m4 | 6 | ||||
-rw-r--r-- | m4/strerror_r.m4 | 3 | ||||
-rw-r--r-- | modules/error | 4 | ||||
-rw-r--r-- | modules/strerror_r-posix | 4 |
6 files changed, 43 insertions, 24 deletions
@@ -1,5 +1,20 @@ 2021-09-08 Paul Eggert <eggert@cs.ucla.edu> + strerror_r-posix: port even better to Android + * lib/strerror_r.c: Use STRERROR_R_CHAR_P to decide whether the + system strerror_r returns char *, and HAVE_DECL_STRERROR_R to + decide whether it either does that or returns an integer. In the + former case, use the system strerror_r even on platforms like + Android API level 23 that don’t have __xpg_strerror_r; also + check for strerror_r failure just in case. + * m4/error.m4 (gl_PREREQ_ERROR): + * m4/strerror_r.m4 (gl_PREREQ_STRERROR_R): + Use system extensions on Android, to avoid mishandling strerror_r + on API level 23 and later. + * modules/error, modules/strerror_r-posix (configure.ac): + Surround gl_PREREQ_ERROR with AS_IF instead of plain if, so that + AC_REQUIREs are propagated out. + strerror_r-posix: port better to Android * m4/strerror_r.m4 (gl_FUNC_STRERROR_R): Move requirement of gl_USE_SYSTEM_EXTENSIONS from here ... diff --git a/lib/strerror_r.c b/lib/strerror_r.c index f0244520b1..90043c2237 100644 --- a/lib/strerror_r.c +++ b/lib/strerror_r.c @@ -34,33 +34,26 @@ #include "strerror-override.h" -#if (__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__) && HAVE___XPG_STRERROR_R /* glibc >= 2.3.4, cygwin >= 1.7.9 */ +#if STRERROR_R_CHAR_P -# define USE_XPG_STRERROR_R 1 -extern -#ifdef __cplusplus -"C" -#endif -int __xpg_strerror_r (int errnum, char *buf, size_t buflen); +# if HAVE___XPG_STRERROR_R +_GL_EXTERN_C int __xpg_strerror_r (int errnum, char *buf, size_t buflen); +# endif -#elif HAVE_DECL_STRERROR_R && !(__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__) +#elif HAVE_DECL_STRERROR_R -/* The system's strerror_r function is OK, except that its third argument +/* The system's strerror_r function's API is OK, except that its third argument is 'int', not 'size_t', or its return type is wrong. */ # include <limits.h> -# define USE_SYSTEM_STRERROR_R 1 - -#else /* (__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__ ? !HAVE___XPG_STRERROR_R : !HAVE_DECL_STRERROR_R) */ +#else /* Use the system's strerror(). Exclude glibc and cygwin because the system strerror_r has the wrong return type, and cygwin 1.7.9 strerror_r clobbers strerror. */ # undef strerror -# define USE_SYSTEM_STRERROR 1 - # if defined __NetBSD__ || defined __hpux || (defined _WIN32 && !defined __CYGWIN__) || defined __sgi || (defined __sun && !defined _LP64) || defined __CYGWIN__ /* No locking needed. */ @@ -166,22 +159,28 @@ strerror_r (int errnum, char *buf, size_t buflen) int ret; int saved_errno = errno; -#if USE_XPG_STRERROR_R +#if STRERROR_R_CHAR_P { + ret = 0; + +# if HAVE___XPG_STRERROR_R ret = __xpg_strerror_r (errnum, buf, buflen); if (ret < 0) ret = errno; +# endif + if (!*buf) { /* glibc 2.13 would not touch buf on err, so we have to fall back to GNU strerror_r which always returns a thread-safe untruncated string to (partially) copy into our buf. */ - safe_copy (buf, buflen, strerror_r (errnum, buf, buflen)); + char *errstring = strerror_r (errnum, buf, buflen); + ret = errstring ? safe_copy (buf, buflen, errstring) : errno; } } -#elif USE_SYSTEM_STRERROR_R +#elif HAVE_DECL_STRERROR_R if (buflen > INT_MAX) buflen = INT_MAX; @@ -245,7 +244,7 @@ strerror_r (int errnum, char *buf, size_t buflen) } # endif -#else /* USE_SYSTEM_STRERROR */ +#else /* strerror_r is not declared. */ /* Try to do what strerror (errnum) does, but without clobbering the buffer used by strerror(). */ diff --git a/m4/error.m4 b/m4/error.m4 index 77f67f78b0..8e3cf95d94 100644 --- a/m4/error.m4 +++ b/m4/error.m4 @@ -1,4 +1,4 @@ -#serial 14 +#serial 15 # Copyright (C) 1996-1998, 2001-2004, 2009-2021 Free Software Foundation, Inc. # @@ -22,6 +22,10 @@ AC_DEFUN([gl_ERROR], # Prerequisites of lib/error.c. AC_DEFUN([gl_PREREQ_ERROR], [ + dnl Use system extensions on Android, so that AC_FUNC_STRERROR_R + dnl discovers the GNU API for strerror_r on Android API level 23 and later. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_REQUIRE([AC_FUNC_STRERROR_R]) : ]) diff --git a/m4/strerror_r.m4 b/m4/strerror_r.m4 index 29b309221f..bc40ec294b 100644 --- a/m4/strerror_r.m4 +++ b/m4/strerror_r.m4 @@ -1,4 +1,4 @@ -# strerror_r.m4 serial 22 +# strerror_r.m4 serial 23 dnl Copyright (C) 2002, 2007-2021 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -37,6 +37,7 @@ AC_DEFUN([gl_FUNC_STRERROR_R], # Prerequisites of lib/strerror_r.c. AC_DEFUN([gl_PREREQ_STRERROR_R], [ + AC_REQUIRE([AC_FUNC_STRERROR_R]) dnl glibc >= 2.3.4 and cygwin 1.7.9 have a function __xpg_strerror_r. AC_CHECK_FUNCS_ONCE([__xpg_strerror_r]) AC_CHECK_FUNCS_ONCE([catgets]) diff --git a/modules/error b/modules/error index 2945c48454..08370da770 100644 --- a/modules/error +++ b/modules/error @@ -15,10 +15,10 @@ msvc-nothrow [test $ac_cv_lib_error_at_line = no] configure.ac: gl_ERROR -if test $ac_cv_lib_error_at_line = no; then +AS_IF([test "$ac_cv_lib_error_at_line" = no], [ AC_LIBOBJ([error]) gl_PREREQ_ERROR -fi +]) m4_ifdef([AM_XGETTEXT_OPTION], [AM_][XGETTEXT_OPTION([--flag=error:3:c-format]) AM_][XGETTEXT_OPTION([--flag=error_at_line:5:c-format])]) diff --git a/modules/strerror_r-posix b/modules/strerror_r-posix index f91bc0e7cc..25f049365a 100644 --- a/modules/strerror_r-posix +++ b/modules/strerror_r-posix @@ -14,10 +14,10 @@ strerror-override [test $HAVE_DECL_STRERROR_R = 0 || test $REPLACE_STRERROR_R = configure.ac: gl_FUNC_STRERROR_R -if test $HAVE_DECL_STRERROR_R = 0 || test $REPLACE_STRERROR_R = 1; then +AS_IF([test $HAVE_DECL_STRERROR_R = 0 || test $REPLACE_STRERROR_R = 1], [ AC_LIBOBJ([strerror_r]) gl_PREREQ_STRERROR_R -fi +]) gl_STRING_MODULE_INDICATOR([strerror_r]) dnl For the modules argp, error. gl_MODULE_INDICATOR([strerror_r-posix]) |