Mercurial > gnulib
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 |
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 | 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 } |