OSDN Git Service

eb5245d598d0451247202f3f25b5c81ed9a1e3d1
[uclinux-h8/uClibc.git] / libc / sysdeps / linux / common / setgroups.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * setgroups() for uClibc
4  *
5  * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
6  *
7  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
8  */
9
10 #include <sys/syscall.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <grp.h>
14
15 #ifdef __USE_BSD
16
17 libc_hidden_proto(setgroups)
18
19 #if defined(__NR_setgroups32)
20 # undef __NR_setgroups
21 # define __NR_setgroups __NR_setgroups32
22 _syscall2(int, setgroups, size_t, size, const gid_t *, list);
23
24 #elif __WORDSIZE == 64
25 _syscall2(int, setgroups, size_t, size, const gid_t *, list);
26
27 #else
28
29 libc_hidden_proto(sysconf)
30
31 #define __NR___syscall_setgroups __NR_setgroups
32 static inline _syscall2(int, __syscall_setgroups,
33                 size_t, size, const __kernel_gid_t *, list);
34
35 int setgroups(size_t size, const gid_t *groups)
36 {
37         if (size > (size_t) sysconf(_SC_NGROUPS_MAX)) {
38 ret_error:
39                 __set_errno(EINVAL);
40                 return -1;
41         } else {
42                 size_t i;
43                 __kernel_gid_t *kernel_groups = NULL;
44
45                 if (size) {
46                         kernel_groups = (__kernel_gid_t *)malloc(sizeof(*kernel_groups) * size);
47                         if (kernel_groups == NULL)
48                                 goto ret_error;
49                 }
50
51                 for (i = 0; i < size; i++) {
52                         kernel_groups[i] = (groups)[i];
53                         if (groups[i] != (gid_t) ((__kernel_gid_t) groups[i])) {
54                                 goto ret_error;
55                         }
56                 }
57
58                 i = __syscall_setgroups(size, kernel_groups);
59                 free(kernel_groups);
60                 return i;
61         }
62 }
63 #endif
64
65 libc_hidden_def(setgroups)
66 #endif