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 */