Skip to main content

rustpython_host_env/
grp.rs

1use std::io;
2
3pub use libc::gid_t;
4
5pub struct Group {
6    pub name: String,
7    pub passwd: String,
8    pub gid: u32,
9    pub mem: Vec<String>,
10}
11
12fn cstr_lossy(s: alloc::ffi::CString) -> String {
13    s.into_string()
14        .unwrap_or_else(|e| e.into_cstring().to_string_lossy().into_owned())
15}
16
17impl From<nix::unistd::Group> for Group {
18    fn from(group: nix::unistd::Group) -> Self {
19        Self {
20            name: group.name,
21            passwd: cstr_lossy(group.passwd),
22            gid: group.gid.as_raw(),
23            mem: group.mem,
24        }
25    }
26}
27
28pub fn getgrgid(gid: libc::gid_t) -> io::Result<Option<Group>> {
29    nix::unistd::Group::from_gid(nix::unistd::Gid::from_raw(gid))
30        .map(|group| group.map(Into::into))
31        .map_err(io::Error::from)
32}
33
34pub fn getgrnam(name: &str) -> io::Result<Option<Group>> {
35    nix::unistd::Group::from_name(name)
36        .map(|group| group.map(Into::into))
37        .map_err(io::Error::from)
38}
39
40pub fn getgrall() -> Vec<Group> {
41    use core::ptr::NonNull;
42
43    static GETGRALL: parking_lot::Mutex<()> = parking_lot::Mutex::new(());
44    let _guard = GETGRALL.lock();
45    let mut list = Vec::new();
46
47    unsafe { libc::setgrent() };
48    while let Some(ptr) = NonNull::new(unsafe { libc::getgrent() }) {
49        let group = nix::unistd::Group::from(unsafe { ptr.as_ref() });
50        list.push(group.into());
51    }
52    unsafe { libc::endgrent() };
53
54    list
55}