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
);