diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-04 18:49:24 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-04 18:56:45 +0200 |
commit | a8cf9c5a3ffd1601872d1ab14c5be00fde29209c (patch) | |
tree | 20d9accf1cfeeea31a7252f6d12889160cf3aab0 /libbb | |
parent | 6a3bcf340aa9d7defc86f21d75fd9412c5b9f427 (diff) | |
download | busybox-w32-a8cf9c5a3ffd1601872d1ab14c5be00fde29209c.tar.gz busybox-w32-a8cf9c5a3ffd1601872d1ab14c5be00fde29209c.tar.bz2 busybox-w32-a8cf9c5a3ffd1601872d1ab14c5be00fde29209c.zip |
libbb: new function bb_getgroups() - allocating wrapper around getgroups()
function old new delta
bb_getgroups - 111 +111
nexpr 843 757 -86
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 0/1 up/down: 111/-86) Total: 25 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/bb_getgroups.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/libbb/bb_getgroups.c b/libbb/bb_getgroups.c new file mode 100644 index 000000000..59ae53738 --- /dev/null +++ b/libbb/bb_getgroups.c | |||
@@ -0,0 +1,47 @@ | |||
1 | /* | ||
2 | * Utility routines. | ||
3 | * | ||
4 | * Copyright (C) 2017 Denys Vlasenko | ||
5 | * | ||
6 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
7 | */ | ||
8 | |||
9 | //kbuild:lib-y += bb_getgroups.o | ||
10 | |||
11 | #include "libbb.h" | ||
12 | |||
13 | gid_t* FAST_FUNC bb_getgroups(int *ngroups, gid_t *group_array) | ||
14 | { | ||
15 | int n = ngroups ? *ngroups : 0; | ||
16 | |||
17 | /* getgroups may be a bit expensive, try to use it only once */ | ||
18 | if (n < 32) | ||
19 | n = 32; | ||
20 | |||
21 | for (;;) { | ||
22 | // FIXME: ash tries so hard to not die on OOM (when we are called from test), | ||
23 | // and we spoil it with just one xrealloc here | ||
24 | group_array = xrealloc(group_array, (n+1) * sizeof(group_array[0])); | ||
25 | n = getgroups(n, group_array); | ||
26 | /* | ||
27 | * If buffer is too small, kernel does not return new_n > n. | ||
28 | * It returns -1 and EINVAL: | ||
29 | */ | ||
30 | if (n >= 0) { | ||
31 | /* Terminator for bb_getgroups(NULL, NULL) usage */ | ||
32 | group_array[n] = (gid_t) -1; | ||
33 | break; | ||
34 | } | ||
35 | if (errno == EINVAL) { /* too small? */ | ||
36 | /* This is the way to ask kernel how big the array is */ | ||
37 | n = getgroups(0, group_array); | ||
38 | continue; | ||
39 | } | ||
40 | /* Some other error (should never happen on Linux) */ | ||
41 | bb_perror_msg_and_die("getgroups"); | ||
42 | } | ||
43 | |||
44 | if (ngroups) | ||
45 | *ngroups = n; | ||
46 | return group_array; | ||
47 | } | ||