2 * <grp.h> wrapper functions.
5 * Jonathan Pryor (jonpryor@vt.edu)
7 * Copyright (C) 2004-2005 Jonathan Pryor
10 #include <sys/types.h>
11 #include <sys/param.h>
17 #include <unistd.h> /* for setgroups on Mac OS X */
25 count_members (char **gr_mem
, int *count
, size_t *mem
)
30 // ensure that later (*mem)+1 doesn't result in integer overflow
31 if (*mem
> INT_MAX
- 1)
34 for (cur
= *gr_mem
; cur
!= NULL
; cur
= *++gr_mem
) {
38 if (!(len
< INT_MAX
- ((*mem
) + 1)))
47 copy_group (struct Mono_Posix_Syscall__Group
*to
, struct group
*from
)
49 size_t nlen
, plen
, buflen
;
53 to
->gr_gid
= from
->gr_gid
;
60 nlen
= strlen (from
->gr_name
);
61 plen
= strlen (from
->gr_passwd
);
65 if (!(nlen
< INT_MAX
- buflen
))
69 if (!(plen
< INT_MAX
- buflen
))
74 count_members (from
->gr_mem
, &count
, &buflen
);
76 to
->_gr_nmem_
= count
;
77 cur
= to
->_gr_buf_
= (char*) malloc (buflen
);
78 to_mem
= to
->gr_mem
= malloc (sizeof(char*)*(count
+1));
79 if (to
->_gr_buf_
== NULL
|| to
->gr_mem
== NULL
) {
85 to
->gr_name
= strcpy (cur
, from
->gr_name
);
87 to
->gr_passwd
= strcpy (cur
, from
->gr_passwd
);
90 for (i
= 0; i
!= count
; ++i
) {
91 to_mem
[i
] = strcpy (cur
, from
->gr_mem
[i
]);
92 cur
+= (strlen (from
->gr_mem
[i
])+1);
100 Mono_Posix_Syscall_getgrnam (const char *name
, struct Mono_Posix_Syscall__Group
*gbuf
)
110 _gbuf
= getgrnam (name
);
114 if (copy_group (gbuf
, _gbuf
) == -1) {
122 Mono_Posix_Syscall_getgrgid (mph_gid_t gid
, struct Mono_Posix_Syscall__Group
*gbuf
)
132 _gbuf
= getgrgid (gid
);
136 if (copy_group (gbuf
, _gbuf
) == -1) {
143 #ifdef HAVE_GETGRNAM_R
145 Mono_Posix_Syscall_getgrnam_r (const char *name
,
146 struct Mono_Posix_Syscall__Group
*gbuf
,
163 buf2
= realloc (buf
, buflen
*= 2);
171 } while ((r
= getgrnam_r (name
, &_grbuf
, buf
, buflen
, (struct group
**) gbufp
)) &&
174 /* On Solaris, this function returns 0 even if the entry was not found */
175 if (r
== 0 && !(*gbufp
))
178 if (r
== 0 && copy_group (gbuf
, &_grbuf
) == -1)
184 #endif /* ndef HAVE_GETGRNAM_R */
186 #ifdef HAVE_GETGRGID_R
188 Mono_Posix_Syscall_getgrgid_r (mph_gid_t gid
,
189 struct Mono_Posix_Syscall__Group
*gbuf
,
206 buf2
= realloc (buf
, buflen
*= 2);
214 } while ((r
= getgrgid_r (gid
, &_grbuf
, buf
, buflen
, (struct group
**) gbufp
)) &&
217 /* On Solaris, this function returns 0 even if the entry was not found */
218 if (r
== 0 && !(*gbufp
))
221 if (r
== 0 && copy_group (gbuf
, &_grbuf
) == -1)
227 #endif /* ndef HAVE_GETGRGID_R */
231 Mono_Posix_Syscall_getgrent (struct Mono_Posix_Syscall__Group
*grbuf
)
245 if (copy_group (grbuf
, gr
) == -1) {
251 #endif /* def HAVE_GETGRENT */
253 #ifdef HAVE_FGETGRENT
255 Mono_Posix_Syscall_fgetgrent (void *stream
, struct Mono_Posix_Syscall__Group
*grbuf
)
265 gr
= fgetgrent ((FILE*) stream
);
269 if (copy_group (grbuf
, gr
) == -1) {
275 #endif /* ndef HAVE_FGETGRENT */
279 Mono_Posix_Syscall_setgroups (mph_size_t size
, mph_gid_t
*list
)
281 mph_return_if_size_t_overflow (size
);
282 return setgroups ((size_t) size
, list
);
284 #endif /* def HAVE_SETGROUPS */
288 Mono_Posix_Syscall_setgrent (void)
293 } while (errno
== EINTR
);
294 mph_return_if_val_in_list5(errno
, EIO
, EMFILE
, ENFILE
, ENOMEM
, ERANGE
);
297 #endif /* def HAVE_SETGRENT */
301 Mono_Posix_Syscall_endgrent (void)
306 #endif /* def HAVE_ENDGRENT */