2 * <grp.h> wrapper functions.
5 * Jonathan Pryor (jonpryor@vt.edu)
7 * Copyright (C) 2004 Jonathan Pryor
10 #include <sys/types.h>
11 #include <sys/param.h>
17 #include <unistd.h> /* for setgroups on Mac OS X */
23 struct Mono_Posix_Syscall__Group {
24 /* string */ char *gr_name;
25 /* string */ char *gr_passwd;
26 /* gid_t */ mph_gid_t gr_gid;
27 /* int */ int _gr_nmem_;
28 /* string */ char **gr_mem;
29 /* string */ char *_gr_buf_; /* holds all but gr_mem */
33 count_members (char **gr_mem, int *count, size_t *mem)
38 // ensure that later (*mem)+1 doesn't result in integer overflow
39 if (*mem > INT_MAX - 1)
42 for (cur = *gr_mem; cur != NULL; cur = *++gr_mem) {
46 if (!(len < INT_MAX - ((*mem) + 1)))
55 copy_group (struct Mono_Posix_Syscall__Group *to, struct group *from)
57 size_t nlen, plen, buflen;
61 to->gr_gid = from->gr_gid;
68 nlen = strlen (from->gr_name);
69 plen = strlen (from->gr_passwd);
73 if (!(nlen < INT_MAX - buflen))
77 if (!(plen < INT_MAX - buflen))
82 count_members (from->gr_mem, &count, &buflen);
84 to->_gr_nmem_ = count;
85 cur = to->_gr_buf_ = (char*) malloc (buflen);
86 to->gr_mem = (char **) malloc (sizeof(char*)*(count+1));
87 if (to->_gr_buf_ == NULL || to->gr_mem == NULL) {
93 to->gr_name = strcpy (cur, from->gr_name);
95 to->gr_passwd = strcpy (cur, from->gr_passwd);
98 for (i = 0; i != count; ++i) {
99 to->gr_mem[i] = strcpy (cur, from->gr_mem[i]);
100 cur += (strlen (from->gr_mem[i])+1);
102 to->gr_mem[i] = NULL;
108 Mono_Posix_Syscall_getgrnam (const char *name, struct Mono_Posix_Syscall__Group *gbuf)
117 _gbuf = getgrnam (name);
121 if (copy_group (gbuf, _gbuf) == -1) {
129 Mono_Posix_Syscall_getgrgid (mph_gid_t gid, struct Mono_Posix_Syscall__Group *gbuf)
138 _gbuf = getgrgid (gid);
142 if (copy_group (gbuf, _gbuf) == -1) {
149 #ifdef HAVE_GETGRNAM_R
151 Mono_Posix_Syscall_getgrnam_r (const char *name,
152 struct Mono_Posix_Syscall__Group *gbuf,
153 struct group **gbufp)
169 buf2 = realloc (buf, buflen *= 2);
176 } while ((r = getgrnam_r (name, &_grbuf, buf, buflen, gbufp)) &&
179 if (r == 0 && copy_group (gbuf, &_grbuf) == -1)
185 #endif /* ndef HAVE_GETGRNAM_R */
187 #ifdef HAVE_GETGRGID_R
189 Mono_Posix_Syscall_getgrgid_r (mph_gid_t gid,
190 struct Mono_Posix_Syscall__Group *gbuf,
191 struct group **gbufp)
207 buf2 = realloc (buf, buflen *= 2);
214 } while ((r = getgrgid_r (gid, &_grbuf, buf, buflen, gbufp)) &&
217 if (r == 0 && copy_group (gbuf, &_grbuf) == -1)
223 #endif /* ndef HAVE_GETGRGID_R */
226 Mono_Posix_Syscall_getgrent (struct Mono_Posix_Syscall__Group *grbuf)
239 if (copy_group (grbuf, gr) == -1) {
246 #ifdef HAVE_FGETGRENT
248 Mono_Posix_Syscall_fgetgrent (FILE *stream, struct Mono_Posix_Syscall__Group *grbuf)
257 gr = fgetgrent (stream);
261 if (copy_group (grbuf, gr) == -1) {
267 #endif /* ndef HAVE_FGETGRENT */
270 Mono_Posix_Syscall_setgroups (mph_size_t size, mph_gid_t *list)
272 mph_return_if_size_t_overflow (size);
273 return setgroups ((size_t) size, list);