Reported by Bruno Haible in
<https://lists.gnu.org/archive/html/bug-gnulib/2024-05/msg00261.html>.

* doc/glibc-functions/getusershell.texi: Mention the musl bug.
* lib/unistd.in.h (getusershell, setusershell, endusershell): Allow the
functions to be declared with the rpl_ prefix.
* m4/getusershell.m4 (gl_FUNC_GETUSERSHELL): Prepare functions to be
replaced on musl systems.
(gl_PREREQ_GETUSERSHELL): New macro.
* m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Initialize
REPLACE_GETUSERSHELL.
* modules/getusershell (Depends-on): Update module conditions to account
for the function being available but replaced by Gnulib.
(configure.ac): Likewise. Invoke gl_PREREQ_GETUSERSHELL.
---
 ChangeLog                             | 17 ++++++++++++
 doc/glibc-functions/getusershell.texi |  5 ++++
 lib/unistd.in.h                       | 39 ++++++++++++++++++++++-----
 m4/getusershell.m4                    | 11 +++++++-
 m4/unistd_h.m4                        |  3 ++-
 modules/getusershell                  | 12 ++++++---
 modules/unistd                        |  1 +
 7 files changed, 76 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1e8cc94054..89c5aa6993 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2024-05-19  Collin Funk  <collin.fu...@gmail.com>
+
+       getusershell: Work around musl bugs.
+       Reported by Bruno Haible in
+       <https://lists.gnu.org/archive/html/bug-gnulib/2024-05/msg00261.html>.
+       * doc/glibc-functions/getusershell.texi: Mention the musl bug.
+       * lib/unistd.in.h (getusershell, setusershell, endusershell): Allow the
+       functions to be declared with the rpl_ prefix.
+       * m4/getusershell.m4 (gl_FUNC_GETUSERSHELL): Prepare functions to be
+       replaced on musl systems.
+       (gl_PREREQ_GETUSERSHELL): New macro.
+       * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Initialize
+       REPLACE_GETUSERSHELL.
+       * modules/getusershell (Depends-on): Update module conditions to account
+       for the function being available but replaced by Gnulib.
+       (configure.ac): Likewise. Invoke gl_PREREQ_GETUSERSHELL.
+
 2024-05-18  Bruno Haible  <br...@clisp.org>
 
        abort-debug: Prefer libbacktrace to execinfo.
diff --git a/doc/glibc-functions/getusershell.texi 
b/doc/glibc-functions/getusershell.texi
index 83b6d4971e..379e6d893f 100644
--- a/doc/glibc-functions/getusershell.texi
+++ b/doc/glibc-functions/getusershell.texi
@@ -14,6 +14,11 @@ @node getusershell
 @item
 This function is missing a declaration on some platforms:
 Solaris 9.
+
+@item
+This function mistakenly returns comments and empty lines on some platforms:
+@c https://www.openwall.com/lists/musl/2024/05/18/1
+musl libc 1.2.4
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 7dbed38969..e01629af25 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -1531,12 +1531,21 @@ _GL_CXXALIASWARN (getpid);
 
 
 #if @GNULIB_GETUSERSHELL@
+# if @REPLACE_GETUSERSHELL@
 /* Return the next valid login shell on the system, or NULL when the end of
    the list has been reached.  */
-# if !@HAVE_DECL_GETUSERSHELL@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#    undef getusershell
+#    define getusershell rpl_getusershell
+#  endif
+_GL_FUNCDECL_RPL (getusershell, char *, (void));
+_GL_CXXALIAS_RPL (getusershell, char *, (void));
+# else
+#  if !@HAVE_DECL_GETUSERSHELL@
 _GL_FUNCDECL_SYS (getusershell, char *, (void));
-# endif
+#  endif
 _GL_CXXALIAS_SYS (getusershell, char *, (void));
+# endif
 _GL_CXXALIASWARN (getusershell);
 #elif defined GNULIB_POSIXCHECK
 # undef getusershell
@@ -1548,10 +1557,19 @@ _GL_WARN_ON_USE (getusershell, "getusershell is 
unportable - "
 
 #if @GNULIB_GETUSERSHELL@
 /* Rewind to pointer that is advanced at each getusershell() call.  */
-# if !@HAVE_DECL_GETUSERSHELL@
+# if @REPLACE_GETUSERSHELL@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#    undef setusershell
+#    define setusershell rpl_setusershell
+#  endif
+_GL_FUNCDECL_RPL (setusershell, void, (void));
+_GL_CXXALIAS_RPL (setusershell, void, (void));
+# else
+#  if !@HAVE_DECL_GETUSERSHELL@
 _GL_FUNCDECL_SYS (setusershell, void, (void));
-# endif
+#  endif
 _GL_CXXALIAS_SYS (setusershell, void, (void));
+# endif
 _GL_CXXALIASWARN (setusershell);
 #elif defined GNULIB_POSIXCHECK
 # undef setusershell
@@ -1564,10 +1582,19 @@ _GL_WARN_ON_USE (setusershell, "setusershell is 
unportable - "
 #if @GNULIB_GETUSERSHELL@
 /* Free the pointer that is advanced at each getusershell() call and
    associated resources.  */
-# if !@HAVE_DECL_GETUSERSHELL@
+# if @REPLACE_GETUSERSHELL@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#    undef endusershell
+#    define endusershell rpl_endusershell
+#  endif
+_GL_FUNCDECL_RPL (endusershell, void, (void));
+_GL_CXXALIAS_RPL (endusershell, void, (void));
+# else
+#  if !@HAVE_DECL_GETUSERSHELL@
 _GL_FUNCDECL_SYS (endusershell, void, (void));
-# endif
+#  endif
 _GL_CXXALIAS_SYS (endusershell, void, (void));
+# endif
 _GL_CXXALIASWARN (endusershell);
 #elif defined GNULIB_POSIXCHECK
 # undef endusershell
diff --git a/m4/getusershell.m4 b/m4/getusershell.m4
index e4ed3f6593..f834151c7d 100644
--- a/m4/getusershell.m4
+++ b/m4/getusershell.m4
@@ -1,5 +1,5 @@
 # getusershell.m4
-# serial 7
+# serial 8
 dnl Copyright (C) 2002-2003, 2006, 2008-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,6 +8,7 @@
 AC_DEFUN([gl_FUNC_GETUSERSHELL],
 [
   AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
 
   dnl Persuade glibc <unistd.h> to declare {get,set,end}usershell().
   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
@@ -26,4 +27,12 @@ AC_DEFUN([gl_FUNC_GETUSERSHELL]
     dnl Assume that on platforms which declare it, the function exists.
     HAVE_DECL_GETUSERSHELL=0
   fi
+  dnl Replace the function on musl unconditionally.
+  dnl See: https://www.openwall.com/lists/musl/2024/05/18/1
+  case "$host_os" in
+    *-musl* | midipix*) REPLACE_GETUSERSHELL=1 ;;
+  esac
 ])
+
+# Prerequisites of lib/getusershell.c.
+AC_DEFUN([gl_PREREQ_GETUSERSHELL], [:])
diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index 81d1b9f616..04fa79c9ca 100644
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -1,5 +1,5 @@
 # unistd_h.m4
-# serial 95
+# serial 96
 dnl Copyright (C) 2006-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -248,6 +248,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS]
   REPLACE_GETPAGESIZE=0;             AC_SUBST([REPLACE_GETPAGESIZE])
   REPLACE_GETPASS=0;                 AC_SUBST([REPLACE_GETPASS])
   REPLACE_GETPASS_FOR_GETPASS_GNU=0; 
AC_SUBST([REPLACE_GETPASS_FOR_GETPASS_GNU])
+  REPLACE_GETUSERSHELL=0;            AC_SUBST([REPLACE_GETUSERSHELL])
   REPLACE_ISATTY=0;                  AC_SUBST([REPLACE_ISATTY])
   REPLACE_LCHOWN=0;                  AC_SUBST([REPLACE_LCHOWN])
   REPLACE_LINK=0;                    AC_SUBST([REPLACE_LINK])
diff --git a/modules/getusershell b/modules/getusershell
index 19929c9b2c..2f47c62e3d 100644
--- a/modules/getusershell
+++ b/modules/getusershell
@@ -8,13 +8,17 @@ m4/getusershell.m4
 Depends-on:
 unistd
 extensions
-fopen-safer          [test $HAVE_GETUSERSHELL = 0]
-unlocked-io-internal [test $HAVE_GETUSERSHELL = 0]
-xalloc               [test $HAVE_GETUSERSHELL = 0]
+fopen-safer          [test $HAVE_GETUSERSHELL = 0 || test 
$REPLACE_GETUSERSHELL = 1]
+unlocked-io-internal [test $HAVE_GETUSERSHELL = 0 || test 
$REPLACE_GETUSERSHELL = 1]
+xalloc               [test $HAVE_GETUSERSHELL = 0 || test 
$REPLACE_GETUSERSHELL = 1]
 
 configure.ac:
 gl_FUNC_GETUSERSHELL
-gl_CONDITIONAL([GL_COND_OBJ_GETUSERSHELL], [test $HAVE_GETUSERSHELL = 0])
+gl_CONDITIONAL([GL_COND_OBJ_GETUSERSHELL],
+               [test $HAVE_GETUSERSHELL = 0 || test $REPLACE_GETUSERSHELL = 1])
+AM_COND_IF([GL_COND_OBJ_GETUSERSHELL], [
+  gl_PREREQ_GETUSERSHELL
+])
 gl_UNISTD_MODULE_INDICATOR([getusershell])
 
 Makefile.am:
diff --git a/modules/unistd b/modules/unistd
index ce2ee04edc..f3c84660c3 100644
--- a/modules/unistd
+++ b/modules/unistd
@@ -205,6 +205,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status 
$(CXXDEFS_H) $(ARG_NONNULL_H
              -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \
              -e 's|@''REPLACE_GETPASS''@|$(REPLACE_GETPASS)|g' \
              -e 
's|@''REPLACE_GETPASS_FOR_GETPASS_GNU''@|$(REPLACE_GETPASS_FOR_GETPASS_GNU)|g' \
+             -e 's|@''REPLACE_GETUSERSHELL''@|$(REPLACE_GETUSERSHELL)|g' \
              -e 's|@''REPLACE_ISATTY''@|$(REPLACE_ISATTY)|g' \
              -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \
              -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \
-- 
2.45.1


Reply via email to