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 */
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
)
118 _gbuf
= getgrnam (name
);
122 if (copy_group (gbuf
, _gbuf
) == -1) {
130 Mono_Posix_Syscall_getgrgid (mph_gid_t gid
, struct Mono_Posix_Syscall__Group
*gbuf
)
140 _gbuf
= getgrgid (gid
);
144 if (copy_group (gbuf
, _gbuf
) == -1) {
151 #ifdef HAVE_GETGRNAM_R
153 Mono_Posix_Syscall_getgrnam_r (const char *name
,
154 struct Mono_Posix_Syscall__Group
*gbuf
,
171 buf2
= realloc (buf
, buflen
*= 2);
179 } while ((r
= getgrnam_r (name
, &_grbuf
, buf
, buflen
, (struct group
**) gbufp
)) &&
182 /* On Solaris, this function returns 0 even if the entry was not found */
183 if (r
== 0 && !(*gbufp
))
186 if (r
== 0 && copy_group (gbuf
, &_grbuf
) == -1)
192 #endif /* ndef HAVE_GETGRNAM_R */
194 #ifdef HAVE_GETGRGID_R
196 Mono_Posix_Syscall_getgrgid_r (mph_gid_t gid
,
197 struct Mono_Posix_Syscall__Group
*gbuf
,
214 buf2
= realloc (buf
, buflen
*= 2);
222 } while ((r
= getgrgid_r (gid
, &_grbuf
, buf
, buflen
, (struct group
**) gbufp
)) &&
225 /* On Solaris, this function returns 0 even if the entry was not found */
226 if (r
== 0 && !(*gbufp
))
229 if (r
== 0 && copy_group (gbuf
, &_grbuf
) == -1)
235 #endif /* ndef HAVE_GETGRGID_R */
238 Mono_Posix_Syscall_getgrent (struct Mono_Posix_Syscall__Group
*grbuf
)
252 if (copy_group (grbuf
, gr
) == -1) {
259 #ifdef HAVE_FGETGRENT
261 Mono_Posix_Syscall_fgetgrent (void *stream
, struct Mono_Posix_Syscall__Group
*grbuf
)
271 gr
= fgetgrent ((FILE*) stream
);
275 if (copy_group (grbuf
, gr
) == -1) {
281 #endif /* ndef HAVE_FGETGRENT */
284 Mono_Posix_Syscall_setgroups (mph_size_t size
, mph_gid_t
*list
)
286 mph_return_if_size_t_overflow (size
);
287 return setgroups ((size_t) size
, list
);
291 Mono_Posix_Syscall_setgrent (void)
295 return errno
== 0 ? 0 : -1;
299 Mono_Posix_Syscall_endgrent (void)
303 return errno
== 0 ? 0 : -1;