bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

getgroups improvements


From: Eric Blake
Subject: getgroups improvements
Date: Thu, 12 Nov 2009 19:28:07 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Based on my work on the gnulib side, how does this look?


From: Eric Blake <address@hidden>
Date: Thu, 12 Nov 2009 11:59:09 -0700
Subject: [PATCH] build: update gnulib, for getgroups improvements

A replacement getgroups is now guaranteed to exist, but it may
fail with ENOSYS.  mgetgroups is moved to gnulib, and now takes
gid_t instead of GETGROUPS_T (but setgroups still needs GETGROUPS_T).

* gnulib: Update to latest.
* gl/modules/mgetgroups: Delete, moved to gnulib.
* gl/m4/mgetgroups.m4: Likewise.
* gl/lib/mgetgroups.h: Likewise.
* gl/lib/mgetgroups.c: Likewise.
* src/group-list.c (print_group_list): Adjust callers.
* src/id.c (print_full_info): Likewise.
---
 gl/lib/mgetgroups.c   |  142 -------------------------------------------------
 gl/lib/mgetgroups.h   |   19 -------
 gl/m4/mgetgroups.m4   |   11 ----
 gl/modules/mgetgroups |   24 --------
 gnulib                |    2 +-
 src/group-list.c      |    6 +--
 src/id.c              |    6 +--
 7 files changed, 5 insertions(+), 205 deletions(-)
 delete mode 100644 gl/lib/mgetgroups.c
 delete mode 100644 gl/lib/mgetgroups.h
 delete mode 100644 gl/m4/mgetgroups.m4
 delete mode 100644 gl/modules/mgetgroups

diff --git a/gl/lib/mgetgroups.c b/gl/lib/mgetgroups.c
deleted file mode 100644
index 0ebc2be..0000000
--- a/gl/lib/mgetgroups.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/* mgetgroups.c -- return a list of the groups a user is in
-
-   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
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-/* Extracted from coreutils' src/id.c. */
-
-#include <config.h>
-
-#include "mgetgroups.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#if HAVE_GETGROUPLIST
-# include <grp.h>
-#endif
-#include "getugroups.h"
-#include "xalloc.h"
-
-
-static GETGROUPS_T *
-realloc_groupbuf (GETGROUPS_T *g, size_t num)
-{
-  if (xalloc_oversized (num, sizeof (*g)))
-    {
-      errno = ENOMEM;
-      return NULL;
-    }
-
-  return realloc (g, num * sizeof (*g));
-}
-
-/* Like getugroups, but store the result in malloc'd storage.
-   Set *GROUPS to the malloc'd list of all group IDs of which USERNAME
-   is a member.  If GID is not -1, store it first.  GID should be the
-   group ID (pw_gid) obtained from getpwuid, in case USERNAME is not
-   listed in the groups database (e.g., /etc/groups).  Upon failure,
-   don't modify *GROUPS, set errno, and return -1.  Otherwise, return
-   the number of groups.  */
-
-int
-mgetgroups (char const *username, gid_t gid, GETGROUPS_T **groups)
-{
-  int max_n_groups;
-  int ng;
-  GETGROUPS_T *g;
-
-#if HAVE_GETGROUPLIST
-  /* We prefer to use getgrouplist if available, because it has better
-     performance characteristics.
-
-     In glibc 2.3.2, getgrouplist is buggy.  If you pass a zero as the
-     length of the output buffer, getgrouplist will still write to the
-     buffer.  Contrary to what some versions of the getgrouplist
-     manpage say, this doesn't happen with nonzero buffer sizes.
-     Therefore our usage here just avoids a zero sized buffer.  */
-  if (username)
-    {
-      enum { N_GROUPS_INIT = 10 };
-      max_n_groups = N_GROUPS_INIT;
-
-      g = realloc_groupbuf (NULL, max_n_groups);
-      if (g == NULL)
-        return -1;
-
-      while (1)
-        {
-          GETGROUPS_T *h;
-          int last_n_groups = max_n_groups;
-
-          /* getgrouplist updates max_n_groups to num required.  */
-          ng = getgrouplist (username, gid, g, &max_n_groups);
-
-          /* Some systems (like Darwin) have a bug where they
-             never increase max_n_groups.  */
-          if (ng < 0 && last_n_groups == max_n_groups)
-            max_n_groups *= 2;
-
-          if ((h = realloc_groupbuf (g, max_n_groups)) == NULL)
-            {
-              int saved_errno = errno;
-              free (g);
-              errno = saved_errno;
-              return -1;
-            }
-          g = h;
-
-          if (0 <= ng)
-            {
-              *groups = g;
-              /* On success some systems just return 0 from getgrouplist,
-                 so return max_n_groups rather than ng.  */
-              return max_n_groups;
-            }
-        }
-    }
-  /* else no username, so fall through and use getgroups. */
-#endif
-
-  max_n_groups = (username
-                  ? getugroups (0, NULL, username, gid)
-                  : getgroups (0, NULL));
-
-  /* If we failed to count groups with NULL for a buffer,
-     try again with a non-NULL one, just in case.  */
-  if (max_n_groups < 0)
-      max_n_groups = 5;
-
-  g = realloc_groupbuf (NULL, max_n_groups);
-  if (g == NULL)
-    return -1;
-
-  ng = (username
-        ? getugroups (max_n_groups, g, username, gid)
-        : getgroups (max_n_groups, g));
-
-  if (ng < 0)
-    {
-      int saved_errno = errno;
-      free (g);
-      errno = saved_errno;
-      return -1;
-    }
-
-  *groups = g;
-  return ng;
-}
diff --git a/gl/lib/mgetgroups.h b/gl/lib/mgetgroups.h
deleted file mode 100644
index 4779fec..0000000
--- a/gl/lib/mgetgroups.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Get a list of all group IDs associated with a specified user ID.
-   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
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-#include <sys/types.h>
-
-int mgetgroups (const char *username, gid_t gid, GETGROUPS_T **groups);
diff --git a/gl/m4/mgetgroups.m4 b/gl/m4/mgetgroups.m4
deleted file mode 100644
index 4b3f328..0000000
--- a/gl/m4/mgetgroups.m4
+++ /dev/null
@@ -1,11 +0,0 @@
-#serial 3
-dnl Copyright (C) 2007-2009 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-AC_DEFUN([gl_MGETGROUPS],
-[
-  AC_CHECK_FUNCS([getgrouplist])
-  AC_LIBOBJ([mgetgroups])
-])
diff --git a/gl/modules/mgetgroups b/gl/modules/mgetgroups
deleted file mode 100644
index 8bce53a..0000000
--- a/gl/modules/mgetgroups
+++ /dev/null
@@ -1,24 +0,0 @@
-Description:
-Return the group IDs of a user in malloc'd storage.
-
-Files:
-lib/mgetgroups.c
-lib/mgetgroups.h
-m4/mgetgroups.m4
-
-Depends-on:
-getugroups
-xalloc
-
-configure.ac:
-gl_MGETGROUPS
-
-Makefile.am:
-
-Include:
-
-License:
-LGPL
-
-Maintainer:
-Jim Meyering
diff --git a/gnulib b/gnulib
index 5ca4b90..5c73d95 160000
--- a/gnulib
+++ b/gnulib
@@ -1 +1 @@
-Subproject commit 5ca4b90d06ed5871ed0bf7bd59dbbf23b69a00ea
+Subproject commit 5c73d953f8ff5fc8cf1554266fbb05ae46c7e1a9
diff --git a/src/group-list.c b/src/group-list.c
index 4c5391d..1fadd0c 100644
--- a/src/group-list.c
+++ b/src/group-list.c
@@ -54,14 +54,13 @@ print_group_list (const char *username,
         ok = false;
     }

-#if HAVE_GETGROUPS
   {
-    GETGROUPS_T *groups;
+    gid_t *groups;
     int i;

     int n_groups = mgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
                                &groups);
-    if (n_groups < 0)
+    if (n_groups < 0 && errno != ENOSYS)
       {
         if (username)
           {
@@ -84,7 +83,6 @@ print_group_list (const char *username,
         }
     free (groups);
   }
-#endif /* HAVE_GETGROUPS */
   return ok;
 }

diff --git a/src/id.c b/src/id.c
index 601e770..9a00f5c 100644
--- a/src/id.c
+++ b/src/id.c
@@ -292,14 +292,13 @@ print_full_info (const char *username)
         printf ("(%s)", grp->gr_name);
     }

-#if HAVE_GETGROUPS
   {
-    GETGROUPS_T *groups;
+    gid_t *groups;
     int i;

     int n_groups = mgetgroups (username, (pwd ? pwd->pw_gid : (gid_t) -1),
                                &groups);
-    if (n_groups < 0)
+    if (n_groups < 0 && errno != ENOSYS)
       {
         if (username)
           {
@@ -327,7 +326,6 @@ print_full_info (const char *username)
       }
     free (groups);
   }
-#endif /* HAVE_GETGROUPS */

   /* POSIX mandates the precise output format, and that it not include
      any context=... part, so skip that if POSIXLY_CORRECT is set.  */
-- 
1.6.4.2







reply via email to

[Prev in Thread] Current Thread [Next in Thread]