annotate lib/mgetgroups.c @ 40231:9b3c79fdfe0b

strtod: fix clash with strtold Problem reported for RHEL 5 by Jesse Caldwell (Bug#34817). * lib/strtod.c (compute_minus_zero, minus_zero): Simplify by remving the macro / external variable, and having just a function. User changed. This avoids the need for an external variable that might clash.
author Paul Eggert <eggert@cs.ucla.edu>
date Mon, 11 Mar 2019 16:40:29 -0700
parents b06060465f09
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
1 /* mgetgroups.c -- return a list of the groups a user or current process is in
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
2
40057
b06060465f09 maint: Run 'make update-copyright'
Paul Eggert <eggert@cs.ucla.edu>
parents: 19484
diff changeset
3 Copyright (C) 2007-2019 Free Software Foundation, Inc.
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
4
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
5 This program is free software: you can redistribute it and/or modify
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
6 it under the terms of the GNU General Public License as published by
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
7 the Free Software Foundation, either version 3 of the License, or
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
8 (at your option) any later version.
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
9
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
10 This program is distributed in the hope that it will be useful,
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
13 GNU General Public License for more details.
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
14
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
15 You should have received a copy of the GNU General Public License
19190
9759915b2aca all: prefer https: URLs
Paul Eggert <eggert@cs.ucla.edu>
parents: 18626
diff changeset
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
17
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
18 /* Extracted from coreutils' src/id.c. */
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
19
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
20 #include <config.h>
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
21
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
22 #include "mgetgroups.h"
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
23
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
24 #include <stdlib.h>
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
25 #include <unistd.h>
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
26 #include <stdint.h>
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
27 #include <string.h>
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
28 #include <errno.h>
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
29 #if HAVE_GETGROUPLIST
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
30 # include <grp.h>
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
31 #endif
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
32
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
33 #include "getugroups.h"
14644
157bb0cdd13a hash, mgetgroups: drop xalloc dependency
Eric Blake <eblake@redhat.com>
parents: 14079
diff changeset
34 #include "xalloc-oversized.h"
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
35
18032
cbcda721f9b4 mgetgroups: port to strict OS X
Paul Eggert <eggert@cs.ucla.edu>
parents: 18029
diff changeset
36 /* Work around an incompatibility of OS X 10.11: getgrouplist
cbcda721f9b4 mgetgroups: port to strict OS X
Paul Eggert <eggert@cs.ucla.edu>
parents: 18029
diff changeset
37 accepts int *, not gid_t *, and int and gid_t differ in sign. */
cbcda721f9b4 mgetgroups: port to strict OS X
Paul Eggert <eggert@cs.ucla.edu>
parents: 18029
diff changeset
38 #if 4 < __GNUC__ + (3 <= __GNUC_MINOR__)
cbcda721f9b4 mgetgroups: port to strict OS X
Paul Eggert <eggert@cs.ucla.edu>
parents: 18029
diff changeset
39 # pragma GCC diagnostic ignored "-Wpointer-sign"
cbcda721f9b4 mgetgroups: port to strict OS X
Paul Eggert <eggert@cs.ucla.edu>
parents: 18029
diff changeset
40 #endif
cbcda721f9b4 mgetgroups: port to strict OS X
Paul Eggert <eggert@cs.ucla.edu>
parents: 18029
diff changeset
41
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
42 static gid_t *
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
43 realloc_groupbuf (gid_t *g, size_t num)
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
44 {
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
45 if (xalloc_oversized (num, sizeof *g))
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
46 {
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
47 errno = ENOMEM;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
48 return NULL;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
49 }
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
50
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
51 return realloc (g, num * sizeof *g);
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
52 }
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
53
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
54 /* Like getugroups, but store the result in malloc'd storage.
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
55 Set *GROUPS to the malloc'd list of all group IDs of which USERNAME
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
56 is a member. If GID is not -1, store it first. GID should be the
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
57 group ID (pw_gid) obtained from getpwuid, in case USERNAME is not
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
58 listed in the groups database (e.g., /etc/groups). If USERNAME is
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
59 NULL, store the supplementary groups of the current process, and GID
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
60 should be -1 or the effective group ID (getegid). Upon failure,
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
61 don't modify *GROUPS, set errno, and return -1. Otherwise, return
12397
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
62 the number of groups. The resulting list may contain duplicates,
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
63 but adjacent members will be distinct. */
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
64
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
65 int
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
66 mgetgroups (char const *username, gid_t gid, gid_t **groups)
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
67 {
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
68 int max_n_groups;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
69 int ng;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
70 gid_t *g;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
71
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
72 #if HAVE_GETGROUPLIST
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
73 /* We prefer to use getgrouplist if available, because it has better
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
74 performance characteristics.
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
75
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
76 In glibc 2.3.2, getgrouplist is buggy. If you pass a zero as the
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
77 length of the output buffer, getgrouplist will still write to the
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
78 buffer. Contrary to what some versions of the getgrouplist
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
79 manpage say, this doesn't happen with nonzero buffer sizes.
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
80 Therefore our usage here just avoids a zero sized buffer. */
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
81 if (username)
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
82 {
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
83 enum { N_GROUPS_INIT = 10 };
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
84 max_n_groups = N_GROUPS_INIT;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
85
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
86 g = realloc_groupbuf (NULL, max_n_groups);
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
87 if (g == NULL)
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
88 return -1;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
89
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
90 while (1)
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
91 {
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
92 gid_t *h;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
93 int last_n_groups = max_n_groups;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
94
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
95 /* getgrouplist updates max_n_groups to num required. */
18032
cbcda721f9b4 mgetgroups: port to strict OS X
Paul Eggert <eggert@cs.ucla.edu>
parents: 18029
diff changeset
96 ng = getgrouplist (username, gid, g, &max_n_groups);
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
97
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
98 /* Some systems (like Darwin) have a bug where they
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
99 never increase max_n_groups. */
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
100 if (ng < 0 && last_n_groups == max_n_groups)
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
101 max_n_groups *= 2;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
102
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
103 if ((h = realloc_groupbuf (g, max_n_groups)) == NULL)
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
104 {
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
105 int saved_errno = errno;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
106 free (g);
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
107 errno = saved_errno;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
108 return -1;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
109 }
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
110 g = h;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
111
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
112 if (0 <= ng)
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
113 {
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
114 *groups = g;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
115 /* On success some systems just return 0 from getgrouplist,
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
116 so return max_n_groups rather than ng. */
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
117 return max_n_groups;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
118 }
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
119 }
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
120 }
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
121 /* else no username, so fall through and use getgroups. */
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
122 #endif
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
123
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
124 max_n_groups = (username
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
125 ? getugroups (0, NULL, username, gid)
12382
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
126 : getgroups (0, NULL));
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
127
12382
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
128 /* If we failed to count groups because there is no supplemental
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
129 group support, then return an array containing just GID.
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
130 Otherwise, we fail for the same reason. */
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
131 if (max_n_groups < 0)
12382
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
132 {
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
133 if (errno == ENOSYS && (g = realloc_groupbuf (NULL, 1)))
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
134 {
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
135 *groups = g;
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
136 *g = gid;
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
137 return gid != (gid_t) -1;
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
138 }
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
139 return -1;
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
140 }
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
141
17514
31bcf897b8c1 mgetgroups: remove dependency on realloc-gnu
Paul Eggert <eggert@cs.ucla.edu>
parents: 17249
diff changeset
142 if (max_n_groups == 0 || (!username && gid != (gid_t) -1))
12382
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
143 max_n_groups++;
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
144 g = realloc_groupbuf (NULL, max_n_groups);
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
145 if (g == NULL)
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
146 return -1;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
147
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
148 ng = (username
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
149 ? getugroups (max_n_groups, g, username, gid)
12416
804bf8e8efd3 mgetgroups: do not write bytes beyond end of malloc'd buffer
Jim Meyering <meyering@redhat.com>
parents: 12411
diff changeset
150 : getgroups (max_n_groups - (gid != (gid_t) -1),
804bf8e8efd3 mgetgroups: do not write bytes beyond end of malloc'd buffer
Jim Meyering <meyering@redhat.com>
parents: 12411
diff changeset
151 g + (gid != (gid_t) -1)));
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
152
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
153 if (ng < 0)
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
154 {
12382
642c575d5700 mgetgroups: add xgetgroups, and avoid ENOSYS failures
Eric Blake <ebb9@byu.net>
parents: 12381
diff changeset
155 /* Failure is unexpected, but handle it anyway. */
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
156 int saved_errno = errno;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
157 free (g);
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
158 errno = saved_errno;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
159 return -1;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
160 }
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
161
12381
e63e3a5265e5 mgetgroups: avoid argument promotion issues with -1
Eric Blake <ebb9@byu.net>
parents: 12281
diff changeset
162 if (!username && gid != (gid_t) -1)
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
163 {
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
164 *g = gid;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
165 ng++;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
166 }
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
167 *groups = g;
12397
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
168
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
169 /* Reduce the number of duplicates. On some systems, getgroups
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
170 returns the effective gid twice: once as the first element, and
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
171 once in its position within the supplementary groups. On other
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
172 systems, getgroups does not return the effective gid at all,
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
173 which is why we provide a GID argument. Meanwhile, the GID
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
174 argument, if provided, is typically any member of the
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
175 supplementary groups, and not necessarily the effective gid. So,
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
176 the most likely duplicates are the first element with an
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
177 arbitrary other element, or pair-wise duplication between the
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
178 first and second elements returned by getgroups. It is possible
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
179 that this O(n) pass will not remove all duplicates, but it is not
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
180 worth the effort to slow down to an O(n log n) algorithm that
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
181 sorts the array in place, nor the extra memory needed for
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
182 duplicate removal via an O(n) hash-table. Hence, this function
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
183 is only documented as guaranteeing no pair-wise duplicates,
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
184 rather than returning the minimal set. */
12411
bff2e832acad mgetgroups: Avoid undefined behaviour when ng == 0.
Bruno Haible <bruno@clisp.org>
parents: 12397
diff changeset
185 if (1 < ng)
bff2e832acad mgetgroups: Avoid undefined behaviour when ng == 0.
Bruno Haible <bruno@clisp.org>
parents: 12397
diff changeset
186 {
bff2e832acad mgetgroups: Avoid undefined behaviour when ng == 0.
Bruno Haible <bruno@clisp.org>
parents: 12397
diff changeset
187 gid_t first = *g;
bff2e832acad mgetgroups: Avoid undefined behaviour when ng == 0.
Bruno Haible <bruno@clisp.org>
parents: 12397
diff changeset
188 gid_t *next;
bff2e832acad mgetgroups: Avoid undefined behaviour when ng == 0.
Bruno Haible <bruno@clisp.org>
parents: 12397
diff changeset
189 gid_t *groups_end = g + ng;
12397
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
190
12411
bff2e832acad mgetgroups: Avoid undefined behaviour when ng == 0.
Bruno Haible <bruno@clisp.org>
parents: 12397
diff changeset
191 for (next = g + 1; next < groups_end; next++)
bff2e832acad mgetgroups: Avoid undefined behaviour when ng == 0.
Bruno Haible <bruno@clisp.org>
parents: 12397
diff changeset
192 {
bff2e832acad mgetgroups: Avoid undefined behaviour when ng == 0.
Bruno Haible <bruno@clisp.org>
parents: 12397
diff changeset
193 if (*next == first || *next == *g)
bff2e832acad mgetgroups: Avoid undefined behaviour when ng == 0.
Bruno Haible <bruno@clisp.org>
parents: 12397
diff changeset
194 ng--;
bff2e832acad mgetgroups: Avoid undefined behaviour when ng == 0.
Bruno Haible <bruno@clisp.org>
parents: 12397
diff changeset
195 else
bff2e832acad mgetgroups: Avoid undefined behaviour when ng == 0.
Bruno Haible <bruno@clisp.org>
parents: 12397
diff changeset
196 *++g = *next;
bff2e832acad mgetgroups: Avoid undefined behaviour when ng == 0.
Bruno Haible <bruno@clisp.org>
parents: 12397
diff changeset
197 }
bff2e832acad mgetgroups: Avoid undefined behaviour when ng == 0.
Bruno Haible <bruno@clisp.org>
parents: 12397
diff changeset
198 }
12397
799c920db2a5 mgetgroups: reduce duplicate listings
Eric Blake <ebb9@byu.net>
parents: 12382
diff changeset
199
12281
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
200 return ng;
9c11ef292284 mgetgroups: new module, taken from coreutils
Eric Blake <ebb9@byu.net>
parents:
diff changeset
201 }