From cf2d7a3bb7e94ec264e44e146841c20cf4192fd4 Mon Sep 17 00:00:00 2001 From: Arcterus Date: Tue, 17 Jun 2014 20:47:29 -0700 Subject: [PATCH 1/6] Fix id and groups for Macs. Also make every util depend on common --- Makefile | 6 +++--- common/c_types.rs | 54 +++++++++++++++++++++++++++++++++++------------ id/id.rs | 2 +- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index d2c81ae6c..b2260d616 100644 --- a/Makefile +++ b/Makefile @@ -97,11 +97,11 @@ command = sh -c '$(1)' # Main exe build rule define EXE_BUILD ifeq ($(wildcard $(1)/Makefile),) -build/$(1): $(1)/$(1).rs | build +build/$(1): $(1)/$(1).rs common/*.rs | build $(call command,$(RUSTC) $(RUSTCFLAGS) -o build/$(1) $(1)/$(1).rs) clean_$(1): else -build/$(1): $(1)/$(1).rs | build +build/$(1): $(1)/$(1).rs common/*.rs | build cd $(1) && make clean_$(1): cd $(1) && make clean @@ -109,7 +109,7 @@ endif endef define CRATE_BUILD -build/$(2): $(1)/$(1).rs | build +build/$(2): $(1)/$(1).rs common/*.rs | build $(call command,$(RUSTC) $(RUSTCFLAGS) --crate-type rlib $(1)/$(1).rs --out-dir build) endef diff --git a/common/c_types.rs b/common/c_types.rs index 5a9e4bb37..53ddc0af9 100644 --- a/common/c_types.rs +++ b/common/c_types.rs @@ -5,6 +5,7 @@ extern crate libc; use self::libc::{ c_char, c_int, + int32_t, uid_t, gid_t, }; @@ -81,16 +82,29 @@ 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 getgrouplist(name: *c_char, - basegid: gid_t, - groups: *mut gid_t, - ngroups: *mut c_int) -> c_int; + pub fn getgrent() -> *c_group; pub fn getgrgid(gid: gid_t) -> *c_group; pub fn getgrnam(name: *c_char) -> *c_group; } +#[cfg(target_os = "macos")] +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(); @@ -137,17 +151,31 @@ pub fn get_group(groupname: &str) -> Option { } } -pub fn get_group_list(name: *c_char, gid: gid_t) -> Result, int> { - let mut ngroups = 0 as c_int; +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); - unsafe { getgrouplist(name, gid, 0 as *mut gid_t, &mut ngroups) }; - let mut groups = Vec::from_elem(ngroups as uint, 0 as gid_t); - let err = unsafe { getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups) }; - if err == -1 { - Err(os::errno()) + if unsafe { getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups as *mut c_int) } == -1 { + groups.reserve(ngroups as uint); + unsafe { getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups); } } else { groups.truncate(ngroups as uint); - Ok(groups) + } + unsafe { groups.set_len(ngroups as uint); } + + groups +} + +#[cfg(target_os = "macos")] +unsafe fn getgrouplist(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); + 0 + } else { + -1 } } @@ -170,7 +198,7 @@ pub fn get_groups() -> Result, int> { pub fn group(possible_pw: Option, nflag: bool) { let groups = match possible_pw { - Some(pw) => get_group_list(pw.pw_name, pw.pw_gid), + Some(pw) => Ok(get_group_list(pw.pw_name, pw.pw_gid)), None => get_groups(), }; diff --git a/id/id.rs b/id/id.rs index c1610c15f..c6581a5d7 100644 --- a/id/id.rs +++ b/id/id.rs @@ -342,7 +342,7 @@ fn id_print(possible_pw: Option, } let groups = match possible_pw { - Some(pw) => get_group_list(pw.pw_name, pw.pw_gid), + Some(pw) => Ok(get_group_list(pw.pw_name, pw.pw_gid)), None => get_groups(), }; From b26b874829775ef2338a73c988dea207e7dec566 Mon Sep 17 00:00:00 2001 From: Arcterus Date: Tue, 17 Jun 2014 20:51:59 -0700 Subject: [PATCH 2/6] common: remove extra cast --- common/c_types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/c_types.rs b/common/c_types.rs index 53ddc0af9..e1015c16f 100644 --- a/common/c_types.rs +++ b/common/c_types.rs @@ -155,7 +155,7 @@ 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 as *mut c_int) } == -1 { + if unsafe { getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups) } == -1 { groups.reserve(ngroups as uint); unsafe { getgrouplist(name, gid, groups.as_mut_ptr(), &mut ngroups); } } else { From ce3b45b50390185f44a33f713be18cf5f71c0412 Mon Sep 17 00:00:00 2001 From: Arcterus Date: Wed, 18 Jun 2014 17:21:17 -0700 Subject: [PATCH 3/6] 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 From 7866f967efe1363e1565ab3fb680cb057b9def28 Mon Sep 17 00:00:00 2001 From: Arcterus Date: Wed, 18 Jun 2014 17:24:56 -0700 Subject: [PATCH 4/6] common: fix for Linux --- common/c_types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/c_types.rs b/common/c_types.rs index ede2d6213..bf91354b9 100644 --- a/common/c_types.rs +++ b/common/c_types.rs @@ -161,7 +161,7 @@ pub fn get_group_list(name: *c_char, gid: gid_t) -> Vec { #[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); + getgrouplist(name, gid, groups, grcnt) } #[cfg(target_os = "macos")] From 3dc206447794b0a8ae5aac3b498630573cdc9cec Mon Sep 17 00:00:00 2001 From: Arcterus Date: Wed, 18 Jun 2014 17:31:00 -0700 Subject: [PATCH 5/6] Begin using dependency info in the Makefile --- Makefile | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index b2260d616..ec7fe788c 100644 --- a/Makefile +++ b/Makefile @@ -96,12 +96,13 @@ command = sh -c '$(1)' # Main exe build rule define EXE_BUILD +-include build/$(1).d ifeq ($(wildcard $(1)/Makefile),) -build/$(1): $(1)/$(1).rs common/*.rs | build - $(call command,$(RUSTC) $(RUSTCFLAGS) -o build/$(1) $(1)/$(1).rs) +build/$(1): $(1)/$(1).rs | build + $(call command,$(RUSTC) $(RUSTCFLAGS) --dep-info build/$(1).d -o build/$(1) $(1)/$(1).rs) clean_$(1): else -build/$(1): $(1)/$(1).rs common/*.rs | build +build/$(1): $(1)/$(1).rs | build cd $(1) && make clean_$(1): cd $(1) && make clean @@ -109,8 +110,9 @@ endif endef define CRATE_BUILD -build/$(2): $(1)/$(1).rs common/*.rs | build - $(call command,$(RUSTC) $(RUSTCFLAGS) --crate-type rlib $(1)/$(1).rs --out-dir build) +-include build/$(1).d +build/$(2): $(1)/$(1).rs | build + $(call command,$(RUSTC) $(RUSTCFLAGS) --crate-type rlib --dep-info build/$(1).d $(1)/$(1).rs --out-dir build) endef # Test exe built rules @@ -128,8 +130,10 @@ all: $(EXES_PATHS) else all: build/uutils +-include build/uutils.d + build/uutils: uutils/uutils.rs $(addprefix build/, $(foreach crate,$(CRATES),$(shell $(RUSTC) --crate-type rlib --crate-file-name $(crate)/$(crate).rs))) - $(RUSTC) $(RUSTCFLAGS) -L build/ uutils/uutils.rs -o $@ + $(RUSTC) $(RUSTCFLAGS) -L build/ --dep-info $@.d uutils/uutils.rs -o $@ endif test: tmp $(addprefix test_,$(TESTS)) From 662b0d656f01571e7b91cc60da630e0cdff2a896 Mon Sep 17 00:00:00 2001 From: Arcterus Date: Wed, 18 Jun 2014 20:23:01 -0700 Subject: [PATCH 6/6] id: remove warning about unused import --- id/id.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/id/id.rs b/id/id.rs index c6581a5d7..e75ba70a2 100644 --- a/id/id.rs +++ b/id/id.rs @@ -21,7 +21,6 @@ extern crate libc; use std::os; use std::ptr::read; use libc::{ - c_int, uid_t, getgid, getuid