bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
* [PATCH] strerror_r-posix: port even better to Android
@ 2021-09-09  2:26 Paul Eggert
  0 siblings, 0 replies; only message in thread
From: Paul Eggert @ 2021-09-09  2:26 UTC (permalink / raw)
  To: bug-gnulib, landfillbaby69; +Cc: Paul Eggert

* 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.
---
 ChangeLog                | 15 +++++++++++++++
 lib/strerror_r.c         | 35 +++++++++++++++++------------------
 m4/error.m4              |  6 +++++-
 m4/strerror_r.m4         |  3 ++-
 modules/error            |  4 ++--
 modules/strerror_r-posix |  4 ++--
 6 files changed, 43 insertions(+), 24 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1db7e333b..7c56ed2a2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 f0244520b..90043c223 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 77f67f78b..8e3cf95d9 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 29b309221..bc40ec294 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 2945c4845..08370da77 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 f91bc0e7c..25f049365 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])
-- 
2.30.2



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2021-09-09  2:26 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-09  2:26 [PATCH] strerror_r-posix: port even better to Android Paul Eggert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).