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