rustpython_host_env/
pwd.rs1use nix::unistd::{self, User};
2use std::io;
3
4#[derive(Debug, Clone)]
5pub struct Passwd {
6 pub name: String,
7 pub passwd: String,
8 pub uid: u32,
9 pub gid: u32,
10 pub gecos: String,
11 pub dir: String,
12 pub shell: String,
13}
14
15impl From<User> for Passwd {
16 fn from(user: User) -> Self {
17 let cstr_lossy = |s: alloc::ffi::CString| {
18 s.into_string()
19 .unwrap_or_else(|e| e.into_cstring().to_string_lossy().into_owned())
20 };
21 let pathbuf_lossy = |p: std::path::PathBuf| {
22 p.into_os_string()
23 .into_string()
24 .unwrap_or_else(|s| s.to_string_lossy().into_owned())
25 };
26 Self {
27 name: user.name,
28 passwd: cstr_lossy(user.passwd),
29 uid: user.uid.as_raw(),
30 gid: user.gid.as_raw(),
31 gecos: cstr_lossy(user.gecos),
32 dir: pathbuf_lossy(user.dir),
33 shell: pathbuf_lossy(user.shell),
34 }
35 }
36}
37
38pub fn getpwnam(name: &str) -> Option<Passwd> {
39 User::from_name(name).ok().flatten().map(Into::into)
40}
41
42pub fn getpwuid(uid: libc::uid_t) -> io::Result<Option<Passwd>> {
43 User::from_uid(unistd::Uid::from_raw(uid))
44 .map(|user| user.map(Into::into))
45 .map_err(io::Error::from)
46}
47
48#[cfg(not(target_os = "android"))]
49pub fn getpwall() -> Vec<Passwd> {
50 static GETPWALL: parking_lot::Mutex<()> = parking_lot::Mutex::new(());
51 let _guard = GETPWALL.lock();
52 let mut list = Vec::new();
53
54 unsafe { libc::setpwent() };
55 while let Some(ptr) = core::ptr::NonNull::new(unsafe { libc::getpwent() }) {
56 list.push(User::from(unsafe { ptr.as_ref() }).into());
57 }
58 unsafe { libc::endpwent() };
59
60 list
61}