From ea5efdbcde3844455ed056cfe486bf0ba0e72df5 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sun, 18 Aug 2019 00:57:48 +0900 Subject: [PATCH] use getgroups(2) for apple macos Although nix-rust/nix mentioned that this feature should be implemented based on opendirectoryd, CPython implemented it based on getgroups(2) for apple macOS. So I ported the code from nix-rust/nix and it works well. ref0: https://github.com/nix-rust/nix/blob/500036a206188dc8f57bf95a7c61616db417038e/src/unistd.rs#L1320 ref1: https://github.com/python/cpython/blob/c4cacc8c5eab50db8da3140353596f38a01115ca/Modules/posixmodule.c#L6852 --- .travis.yml | 16 +++++++++++++++- vm/src/stdlib/os.rs | 28 +++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed419dc75..0d45058c3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,8 +12,22 @@ before_cache: matrix: fast_finish: true include: - - name: Run Rust tests + - name: Run Rust tests(linux) language: rust + os: linux + rust: stable + cache: cargo + script: + - cargo build --verbose --all + - cargo test --verbose --all + env: + # Prevention of cache corruption. + # See: https://docs.travis-ci.com/user/caching/#caches-and-build-matrices + - JOBCACHE=1 + + - name: Run Rust tests(osx) + language: rust + os: osx rust: stable cache: cargo script: diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index bf63efbbc..d206270df 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -262,7 +262,7 @@ fn get_right_permission( let others_permissions = get_permissions(others_mode); let user_id = nix::unistd::getuid(); - let groups_ids = nix::unistd::getgroups()?; + let groups_ids = getgroups()?; if file_owner == user_id { Ok(owner_permissions) @@ -273,6 +273,32 @@ fn get_right_permission( } } +#[cfg(target_os = "macos")] +fn getgroups() -> nix::Result> { + use libc::{c_int, gid_t}; + use std::ptr; + let ret = unsafe { libc::getgroups(0, ptr::null_mut()) }; + let mut groups = Vec::::with_capacity(Errno::result(ret)? as usize); + loop { + let ret = unsafe { + libc::getgroups( + groups.capacity() as c_int, + groups.as_mut_ptr() as *mut gid_t, + ) + }; + + return Errno::result(ret).map(|s| { + unsafe { groups.set_len(s as usize) }; + groups + }); + } +} + +#[cfg(target_os = "linux")] +fn getgroups() -> nix::Result> { + nix::unistd::getgroups() +} + #[cfg(unix)] fn os_access(path: PyStringRef, mode: u8, vm: &VirtualMachine) -> PyResult { use std::os::unix::fs::MetadataExt;