changeset 18029:e4a13d95b503

mgetgroups: port to strict OS X * doc/glibc-functions/getgrouplist.texi (getgrouplist): Document the getgrouplist problem. * lib/mgetgroups.c (getgrouplist_gids) [HAVE_GETGROUPLIST]: New macro. (mgetgroups): Use it. * m4/mgetgroups.m4 (gl_MGETGROUPS): Check for OS X signature for getgrouplist.
author Paul Eggert <eggert@cs.ucla.edu>
date Sun, 28 Jun 2015 23:43:35 -0700
parents 4b0e76619c7f
children bbdce0795bb7
files doc/glibc-functions/getgrouplist.texi lib/mgetgroups.c m4/mgetgroups.m4
diffstat 3 files changed, 48 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/doc/glibc-functions/getgrouplist.texi
+++ b/doc/glibc-functions/getgrouplist.texi
@@ -11,6 +11,10 @@
 Portability problems not fixed by Gnulib:
 @itemize
 @item
+This function takes @code{int} instead of @code{gid_t} parameters
+on some platforms: OS X 10.11.
+
+@item
 This function is missing on some platforms:
 Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11 2011-11, Cygwin 1.7.9, mingw, MSVC 9, BeOS.
 @end itemize
--- a/lib/mgetgroups.c
+++ b/lib/mgetgroups.c
@@ -64,6 +64,11 @@
   gid_t *g;
 
 #if HAVE_GETGROUPLIST
+# if HAVE_GETGROUPLIST_WITH_INT
+#  define getgrouplist_gids(g) ((int *) (g))
+# else
+#  define getgrouplist_gids(g) (g)
+# endif
   /* We prefer to use getgrouplist if available, because it has better
      performance characteristics.
 
@@ -87,7 +92,8 @@
           int last_n_groups = max_n_groups;
 
           /* getgrouplist updates max_n_groups to num required.  */
-          ng = getgrouplist (username, gid, g, &max_n_groups);
+          ng = getgrouplist (username, gid, getgrouplist_gids (g),
+                             &max_n_groups);
 
           /* Some systems (like Darwin) have a bug where they
              never increase max_n_groups.  */
--- a/m4/mgetgroups.m4
+++ b/m4/mgetgroups.m4
@@ -1,4 +1,4 @@
-#serial 5
+#serial 6
 dnl Copyright (C) 2007-2015 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -6,5 +6,41 @@
 
 AC_DEFUN([gl_MGETGROUPS],
 [
+  AC_CHECK_HEADERS_ONCE([grp.h])
   AC_CHECK_FUNCS_ONCE([getgrouplist])
+  if test "$ac_cv_func_getgrouplist" = yes; then
+    AC_CACHE_CHECK([for getgrouplist with int signature],
+      [gl_cv_getgrouplist_with_int],
+      [gl_cv_getgrouplist_with_int=no
+       AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM(
+            [[#if HAVE_GRP_H
+               #include <grp.h>
+              #endif
+              int groups[1];
+              int ngroups = 1;
+              int getgrouplist (char const *, gid_t, gid_t *, int *);
+            ]],
+            [[
+              return - getgrouplist ("root", 0, groups, &ngroups);
+            ]])],
+         [],
+         [AC_COMPILE_IFELSE(
+           [AC_LANG_PROGRAM(
+              [[#if HAVE_GRP_H
+                 #include <grp.h>
+                #endif
+                int groups[sizeof (gid_t) == sizeof (int) ? 1 : -1];
+                int ngroups = 1;
+                int getgrouplist (char const *, int, int *, int *);
+              ]],
+              [[
+                return - getgrouplist ("root", 0, groups, &ngroups);
+              ]])],
+            [gl_cv_getgrouplist_with_int=yes])])])
+    if test "$gl_cv_getgrouplist_with_int" = yes; then
+      AC_DEFINE([HAVE_GETGROUPLIST_WITH_INT], 1,
+        [Define to 1 if getgrouplist accepts and returns int and not gid_t.])
+    fi
+  fi
 ])