Mercurial > hg > octave-shane > gnulib-hg
changeset 12280:39be377f1765
getgroups: don't expose GETGROUPS_T to user
These days, most systems already declare getgroups with gid_t*.
But in the rare case that GETGROUPS_T is still int but gid_t
is short, the user should not have to uglify their code; let
the replacement hide all the magic.
Tested by configuring with ac_cv_type_getgroups=uint64_t on a
platform with 32-bit gid_t, and ignoring compiler warnings.
However, since we don't replace setgroups, the GETGROUPS_T
workaround is still needed there for now.
* lib/getgroups.c (rpl_getgroups): Change signature. Copy array
an element at a time if GETGROUPS_T is wrong size.
* lib/getugroups.h (getugroups): Change signature.
* lib/unistd.in.h (getgroups): Likewise.
* m4/getgroups.m4 (gl_FUNC_GETGROUPS): Use replacement if
signature needs fixing.
* m4/getugroups.m4 (gl_GETUGROUPS): No longer need
AC_TYPE_GETGROUPS.
* modules/group-member (Depends-on): Add getgroups.
* lib/group-member.c (group_info, get_group_info): Use gid_t.
(group_member): Rely on getgroups replacement.
* lib/getugroups.c (getugroups): Use gid_t.
* tests/test-getgroups.c (main): Likewise.
* NEWS: Mention the signature change.
* doc/posix-functions/getgroups.texi (getgroups): Mention the
problem with signature.
* doc/glibc-functions/setgroups.texi (setgroups): Mention that
GETGROUPS_T is still useful for setgroups.
Signed-off-by: Eric Blake <ebb9@byu.net>
author | Eric Blake <ebb9@byu.net> |
---|---|
date | Thu, 12 Nov 2009 10:19:39 -0700 |
parents | 6a41b8f5f874 |
children | 9c11ef292284 |
files | ChangeLog NEWS doc/glibc-functions/setgroups.texi doc/posix-functions/getgroups.texi lib/getgroups.c lib/getugroups.c lib/getugroups.h lib/group-member.c lib/unistd.in.h m4/getgroups.m4 m4/getugroups.m4 modules/group-member tests/test-getgroups.c |
diffstat | 13 files changed, 87 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,25 @@ 2009-11-13 Eric Blake <ebb9@byu.net> + getgroups: don't expose GETGROUPS_T to user + * lib/getgroups.c (rpl_getgroups): Change signature. Copy array + an element at a time if GETGROUPS_T is wrong size. + * lib/getugroups.h (getugroups): Change signature. + * lib/unistd.in.h (getgroups): Likewise. + * m4/getgroups.m4 (gl_FUNC_GETGROUPS): Use replacement if + signature needs fixing. + * m4/getugroups.m4 (gl_GETUGROUPS): No longer need + AC_TYPE_GETGROUPS. + * modules/group-member (Depends-on): Add getgroups. + * lib/group-member.c (group_info, get_group_info): Use gid_t. + (group_member): Rely on getgroups replacement. + * lib/getugroups.c (getugroups): Use gid_t. + * tests/test-getgroups.c (main): Likewise. + * NEWS: Mention the signature change. + * doc/posix-functions/getgroups.texi (getgroups): Mention the + problem with signature. + * doc/glibc-functions/setgroups.texi (setgroups): Mention that + GETGROUPS_T is still useful for setgroups. + getgroups, getugroups: provide stubs for mingw * lib/getgroups.c (getgroups): Provide ENOSYS stub for mingw. * lib/getugroups.c (getugroups): Likewise.
--- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ Date Modules Changes +2009-11-12 getgroups These functions now use a signature of gid_t, + getugroups rather than GETGROUPS_T. This probably has no + effect except on very old platforms. + 2009-11-04 tempname The gen_tempname function takes an additional 'suffixlen' argument. You can safely pass 0.
--- a/doc/glibc-functions/setgroups.texi +++ b/doc/glibc-functions/setgroups.texi @@ -13,4 +13,10 @@ @item This function is missing on some platforms: AIX 5.1, mingw, Interix 3.5, BeOS. +@item +On very old systems, this function operated on an array of @samp{int}, +even though that was a different size than an array of @samp{gid_t}; +you can use autoconf's AC_TYPE_GETGROUPS to set @code{GETGROUPS_T} to +the appropriate size (since @code{getgroups} and @code{setgroups} +share the same bug). @end itemize
--- a/doc/posix-functions/getgroups.texi +++ b/doc/posix-functions/getgroups.texi @@ -14,6 +14,9 @@ @item On Ultrix 4.3, @code{getgroups (0, 0)} always fails. See macro @samp{AC_FUNC_GETGROUPS}. +@item +On very old systems, this function operated on an array of @samp{int}, +even though that was a different size than an array of @samp{gid_t}. @end itemize Portability problems not fixed by Gnulib:
--- a/lib/getgroups.c +++ b/lib/getgroups.c @@ -48,14 +48,44 @@ whether the effective group id is included in the list. */ int -rpl_getgroups (int n, GETGROUPS_T *group) +rpl_getgroups (int n, gid_t *group) { int n_groups; GETGROUPS_T *gbuf; int saved_errno; if (n != 0) - return getgroups (n, group); + { + int result; + int saved_errno; + if (sizeof *group == sizeof *gbuf) + return getgroups (n, (GETGROUPS_T *) group); + + if (n < 0) + { + errno = EINVAL; + return -1; + } + if (SIZE_MAX / sizeof *gbuf <= n) + { + errno = ENOMEM; + return -1; + } + gbuf = malloc (n * sizeof *gbuf); + if (!gbuf) + return -1; + result = getgroups (n, gbuf); + if (0 <= result) + { + n = result; + while (n--) + group[n] = gbuf[n]; + } + saved_errno = errno; + free (gbuf); + errno == saved_errno; + return result; + } n = 20; while (1)
--- a/lib/getugroups.c +++ b/lib/getugroups.c @@ -55,7 +55,7 @@ Otherwise, return the number of IDs we've written into GROUPLIST. */ int -getugroups (int maxcount, GETGROUPS_T *grouplist, char const *username, +getugroups (int maxcount, gid_t *grouplist, char const *username, gid_t gid) { int count = 0;
--- a/lib/getugroups.h +++ b/lib/getugroups.h @@ -1,5 +1,5 @@ /* Get a list of group IDs associated with a specified user ID. - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,5 +15,5 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <sys/types.h> -int getugroups (int maxcount, GETGROUPS_T *grouplist, char const *username, - gid_t gid); +int getugroups (int maxcount, gid_t *grouplist, char const *username, + gid_t gid);
--- a/lib/group-member.c +++ b/lib/group-member.c @@ -1,6 +1,6 @@ /* group-member.c -- determine whether group id is in calling user's group list - Copyright (C) 1994, 1997, 1998, 2003, 2005, 2006 Free Software + Copyright (C) 1994, 1997, 1998, 2003, 2005, 2006, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -32,11 +32,9 @@ struct group_info { int n_groups; - GETGROUPS_T *group; + gid_t *group; }; -#if HAVE_GETGROUPS - static void free_group_info (struct group_info const *g) { @@ -48,7 +46,7 @@ { int n_groups; int n_group_slots = getgroups (0, NULL); - GETGROUPS_T *group; + gid_t *group; if (n_group_slots < 0) return false; @@ -72,18 +70,14 @@ return true; } -#endif /* not HAVE_GETGROUPS */ - /* Return non-zero if GID is one that we have in our groups list. - If there is no getgroups function, return non-zero if GID matches - either of the current or effective group IDs. */ + Note that the groups list is not guaranteed to contain the current + or effective group ID, so they should generally be checked + separately. */ int group_member (gid_t gid) { -#ifndef HAVE_GETGROUPS - return ((gid == getgid ()) || (gid == getegid ())); -#else int i; int found; struct group_info gi; @@ -96,16 +90,15 @@ for (i = 0; i < gi.n_groups; i++) { if (gid == gi.group[i]) - { - found = 1; - break; - } + { + found = 1; + break; + } } free_group_info (&gi); return found; -#endif /* HAVE_GETGROUPS */ } #ifdef TEST @@ -119,7 +112,7 @@ program_name = argv[0]; - for (i=1; i<argc; i++) + for (i = 1; i < argc; i++) { gid_t gid;
--- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -417,7 +417,7 @@ If N is 0, return the group count; otherwise, N describes how many entries are available in GROUPS. Return -1 and set errno if N is not 0 and not large enough. Fails with ENOSYS on some systems. */ -int getgroups (int n, GETGROUPS_T *groups); +int getgroups (int n, gid_t *groups); # endif #elif defined GNULIB_POSIXCHECK # undef getgroups
--- a/m4/getgroups.m4 +++ b/m4/getgroups.m4 @@ -1,4 +1,4 @@ -# serial 13 +# serial 14 dnl From Jim Meyering. dnl A wrapper around AC_FUNC_GETGROUPS. @@ -17,7 +17,8 @@ if test "$ac_cv_func_getgroups" != yes; then AC_LIBOBJ([getgroups]) HAVE_GETGROUPS=0 - elif test "$ac_cv_func_getgroups_works" != yes; then + elif test "$ac_cv_func_getgroups_works.$ac_cv_type_getgroups" != yes.gid_t + then AC_LIBOBJ([getgroups]) REPLACE_GETGROUPS=1 fi
--- a/m4/getugroups.m4 +++ b/m4/getugroups.m4 @@ -1,4 +1,4 @@ -# getugroups.m4 serial 7 +# getugroups.m4 serial 8 dnl Copyright (C) 2002, 2003, 2005, 2006, 2009 Free Software dnl Foundation, Inc. dnl This file is free software; the Free Software Foundation @@ -9,7 +9,4 @@ [ AC_LIBOBJ([getugroups]) AC_CHECK_HEADERS_ONCE([grp.h]) - - dnl Prerequisites of lib/getugroups.c. - AC_TYPE_GETGROUPS ])