2 * <grp.h> wrapper functions.
5 * Jonathan Pryor (jonpryor@vt.edu)
7 * Copyright (C) 2004-2005 Jonathan Pryor
10 #include <sys/types.h>
11 #ifdef HAVE_SYS_PARAM_H
12 #include <sys/param.h>
19 #include <unistd.h> /* for setgroups on Mac OS X */
27 count_members (char **gr_mem, int *count, size_t *mem)
32 // ensure that later (*mem)+1 doesn't result in integer overflow
33 if (*mem > INT_MAX - 1)
36 for (cur = *gr_mem; cur != NULL; cur = *++gr_mem) {
40 if (!(len < INT_MAX - ((*mem) + 1)))
49 copy_group (struct Mono_Posix_Syscall__Group *to, struct group *from)
51 size_t nlen, plen, buflen;
55 to->gr_gid = from->gr_gid;
62 nlen = strlen (from->gr_name);
63 plen = strlen (from->gr_passwd);
67 if (!(nlen < INT_MAX - buflen))
71 if (!(plen < INT_MAX - buflen))
76 count_members (from->gr_mem, &count, &buflen);
78 to->_gr_nmem_ = count;
79 cur = to->_gr_buf_ = (char*) malloc (buflen);
80 to_mem = to->gr_mem = malloc (sizeof(char*)*(count+1));
81 if (to->_gr_buf_ == NULL || to->gr_mem == NULL) {
87 to->gr_name = strcpy (cur, from->gr_name);
89 to->gr_passwd = strcpy (cur, from->gr_passwd);
92 for (i = 0; i != count; ++i) {
93 to_mem [i] = strcpy (cur, from->gr_mem[i]);
94 cur += (strlen (from->gr_mem[i])+1);
102 Mono_Posix_Syscall_getgrnam (const char *name, struct Mono_Posix_Syscall__Group *gbuf)
112 _gbuf = getgrnam (name);
116 if (copy_group (gbuf, _gbuf) == -1) {
124 Mono_Posix_Syscall_getgrgid (mph_gid_t gid, struct Mono_Posix_Syscall__Group *gbuf)
134 _gbuf = getgrgid (gid);
138 if (copy_group (gbuf, _gbuf) == -1) {
145 #ifdef HAVE_GETGRNAM_R
147 Mono_Posix_Syscall_getgrnam_r (const char *name,
148 struct Mono_Posix_Syscall__Group *gbuf,
165 buf2 = realloc (buf, buflen *= 2);
173 } while ((r = getgrnam_r (name, &_grbuf, buf, buflen, (struct group**) gbufp)) &&
176 /* On Solaris, this function returns 0 even if the entry was not found */
177 if (r == 0 && !(*gbufp))
180 if (r == 0 && copy_group (gbuf, &_grbuf) == -1)
186 #endif /* ndef HAVE_GETGRNAM_R */
188 #ifdef HAVE_GETGRGID_R
190 Mono_Posix_Syscall_getgrgid_r (mph_gid_t gid,
191 struct Mono_Posix_Syscall__Group *gbuf,
208 buf2 = realloc (buf, buflen *= 2);
216 } while ((r = getgrgid_r (gid, &_grbuf, buf, buflen, (struct group**) gbufp)) &&
219 /* On Solaris, this function returns 0 even if the entry was not found */
220 if (r == 0 && !(*gbufp))
223 if (r == 0 && copy_group (gbuf, &_grbuf) == -1)
229 #endif /* ndef HAVE_GETGRGID_R */
233 Mono_Posix_Syscall_getgrent (struct Mono_Posix_Syscall__Group *grbuf)
247 if (copy_group (grbuf, gr) == -1) {
253 #endif /* def HAVE_GETGRENT */
255 #ifdef HAVE_FGETGRENT
257 Mono_Posix_Syscall_fgetgrent (void *stream, struct Mono_Posix_Syscall__Group *grbuf)
267 gr = fgetgrent ((FILE*) stream);
271 if (copy_group (grbuf, gr) == -1) {
277 #endif /* ndef HAVE_FGETGRENT */
281 Mono_Posix_Syscall_setgroups (mph_size_t size, mph_gid_t *list)
283 mph_return_if_size_t_overflow (size);
284 return setgroups ((size_t) size, list);
286 #endif /* def HAVE_SETGROUPS */
290 Mono_Posix_Syscall_setgrent (void)
295 } while (errno == EINTR);
296 mph_return_if_val_in_list5(errno, EIO, EMFILE, ENFILE, ENOMEM, ERANGE);
299 #endif /* def HAVE_SETGRENT */
303 Mono_Posix_Syscall_endgrent (void)
308 #endif /* def HAVE_ENDGRENT */