|
1 | 1 | use serde::Serialize; |
| 2 | +use snafu::{OptionExt, ResultExt, Snafu}; |
| 3 | +use sysinfo::{Gid, Pid, Uid}; |
| 4 | + |
| 5 | +use crate::error::SysinfoError; |
| 6 | + |
| 7 | +#[derive(Debug, Snafu)] |
| 8 | +pub enum Error { |
| 9 | + #[snafu(display("failed to get pid of the current process"))] |
| 10 | + GetCurrentPid { source: SysinfoError }, |
| 11 | + #[snafu(display("current pid {pid} could not be resolved to a proess"))] |
| 12 | + ResolveCurrentProcess { pid: Pid }, |
| 13 | +} |
| 14 | +type Result<T, E = Error> = std::result::Result<T, E>; |
2 | 15 |
|
3 | 16 | #[derive(Debug, Serialize)] |
4 | 17 | pub struct User { |
5 | 18 | pub name: Option<String>, // The name of the current user |
6 | | - pub uid: u32, // The user ID (UID) |
7 | | - pub gid: u32, // The group ID (GID) |
| 19 | + pub uid: Option<Uid>, // The user ID (UID) |
| 20 | + pub gid: Option<Gid>, // The group ID (GID) |
8 | 21 | } |
9 | 22 |
|
10 | 23 | impl User { |
11 | | - pub fn collect_current() -> Self { |
12 | | - let uid = users::get_current_uid(); |
| 24 | + #[tracing::instrument(name = "User::collect_current", skip(sys))] |
| 25 | + pub fn collect_current(sys: &sysinfo::System) -> Result<Self> { |
| 26 | + let pid = sysinfo::get_current_pid() |
| 27 | + .map_err(|msg| SysinfoError { msg }) |
| 28 | + .context(GetCurrentPidSnafu)?; |
| 29 | + let current_process = sys |
| 30 | + .process(pid) |
| 31 | + .context(ResolveCurrentProcessSnafu { pid })?; |
| 32 | + let uid = current_process.user_id(); |
| 33 | + let os_users = sysinfo::Users::new_with_refreshed_list(); |
13 | 34 | let user = Self { |
14 | | - name: users::get_user_by_uid(uid).map(|user| user.name().to_string_lossy().to_string()), |
15 | | - uid, |
16 | | - gid: users::get_current_gid(), |
| 35 | + name: uid.and_then(|uid| Some(os_users.get_user_by_id(uid)?.name().to_string())), |
| 36 | + uid: uid.cloned(), |
| 37 | + gid: current_process.group_id(), |
17 | 38 | }; |
18 | | - tracing::info!(user.name, user.uid, user.gid, "current user"); |
19 | | - user |
| 39 | + tracing::info!( |
| 40 | + user.name, |
| 41 | + user.uid = user.uid.as_ref().map(|uid| format!("{uid:?}")), |
| 42 | + user.gid = user.uid.as_ref().map(|gid| format!("{gid:?}")), |
| 43 | + "current user" |
| 44 | + ); |
| 45 | + Ok(user) |
20 | 46 | } |
21 | 47 | } |
0 commit comments