From ce3b45b50390185f44a33f713be18cf5f71c0412 Mon Sep 17 00:00:00 2001 From: Arcterus Date: Wed, 18 Jun 2014 17:21:17 -0700 Subject: [PATCH] common: make get_group_list work for all users on Macs --- common/c_types.rs | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/common/c_types.rs b/common/c_types.rs index e1015c16f..ede2d6213 100644 --- a/common/c_types.rs +++ b/common/c_types.rs @@ -82,14 +82,14 @@ pub struct c_tm { } extern { - pub fn setgrent(); - pub fn endgrent(); - pub fn getpwuid(uid: uid_t) -> *c_passwd; pub fn getpwnam(login: *c_char) -> *c_passwd; - pub fn getgrent() -> *c_group; pub fn getgrgid(gid: gid_t) -> *c_group; pub fn getgrnam(name: *c_char) -> *c_group; + pub fn getgrouplist(name: *c_char, + gid: gid_t, + groups: *mut gid_t, + ngroups: *mut c_int) -> c_int; } #[cfg(target_os = "macos")] @@ -97,14 +97,6 @@ extern { pub fn getgroupcount(name: *c_char, gid: gid_t) -> int32_t; } -#[cfg(target_os = "linux")] -extern { - pub fn getgrouplist(name: *c_char, - gid: gid_t, - groups: *mut gid_t, - ngroups: *mut c_int) -> c_int; -} - pub fn get_pw_from_args(free: &Vec) -> Option { if free.len() == 1 { let username = free.get(0).as_slice(); @@ -155,9 +147,9 @@ pub fn get_group_list(name: *c_char, gid: gid_t) -> Vec { let mut ngroups: c_int = 32; let mut groups: Vec = Vec::with_capacity(ngroups as uint); - if unsafe { getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups) } == -1 { + if unsafe { get_group_list_internal(name, gid, groups.as_mut_ptr(), &mut ngroups) } == -1 { groups.reserve(ngroups as uint); - unsafe { getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups); } + unsafe { get_group_list_internal(name, gid, groups.as_mut_ptr(), &mut ngroups); } } else { groups.truncate(ngroups as uint); } @@ -166,13 +158,19 @@ pub fn get_group_list(name: *c_char, gid: gid_t) -> Vec { groups } +#[cfg(target_os = "linux")] +#[inline(always)] +unsafe fn get_group_list_internal(name: *c_char, gid: gid_t, groups: *mut gid_t, grcnt: *mut c_int) -> c_int { + getgrouplist(name, gid, groups, grcnt); +} + #[cfg(target_os = "macos")] -unsafe fn getgrouplist(name: *c_char, gid: gid_t, groups: *mut gid_t, grcnt: *mut c_int) -> c_int { +unsafe fn get_group_list_internal(name: *c_char, gid: gid_t, groups: *mut gid_t, grcnt: *mut c_int) -> c_int { let ngroups = getgroupcount(name, gid); let oldsize = *grcnt; *grcnt = ngroups; if oldsize >= ngroups { - getgroups(ngroups, groups); + getgrouplist(name, gid, groups, grcnt); 0 } else { -1