diff --git a/doc/glibc-functions/getgrouplist.texi b/doc/glibc-functions/getgrouplist.texi index 8a37cb1e9d..0295caea49 100644 --- a/doc/glibc-functions/getgrouplist.texi +++ b/doc/glibc-functions/getgrouplist.texi @@ -10,6 +10,10 @@ Portability problems fixed by Gnulib: 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. diff --git a/lib/mgetgroups.c b/lib/mgetgroups.c index f31f4d15f8..dd0c7a595c 100644 --- a/lib/mgetgroups.c +++ b/lib/mgetgroups.c @@ -64,6 +64,11 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) 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 @@ mgetgroups (char const *username, gid_t gid, gid_t **groups) 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. */ diff --git a/m4/mgetgroups.m4 b/m4/mgetgroups.m4 index 42b5cf83a5..5f19d4f606 100644 --- 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 @@ dnl with or without modifications, as long as this notice is preserved. 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 + #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 + #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 ])