mprober_lib/process/
process_status.rs

1use std::{io::ErrorKind, path::Path};
2
3use crate::scanner_rust::{generic_array::typenum::U192, ScannerAscii, ScannerError};
4
5#[derive(Default, Debug, Clone)]
6pub struct ProcessStatus {
7    /// The user who created this process or the UID set via `setuid()` by the root caller.
8    pub real_uid:      u32,
9    /// The group who created this process or the GID set via `setgid()` by the root caller.
10    pub real_gid:      u32,
11    /// The UID set via `setuid()` by the caller.
12    pub effective_uid: u32,
13    /// The GID set via `setgid()` by the caller.
14    pub effective_gid: u32,
15    /// The UID set via `setuid()` by the root caller
16    pub saved_set_uid: u32,
17    /// The GID set via `setgid()` by the root caller
18    pub saved_set_gid: u32,
19    /// The UID of the running executable file of this process.
20    pub fs_uid:        u32,
21    /// The GID of the running executable file of this process.
22    pub fs_gid:        u32,
23}
24
25/// Get the status of a specific process found by ID by reading the `/proc/PID/status` file.
26///
27/// ```rust
28/// use mprober_lib::process;
29///
30/// let process_status = process::get_process_status(1).unwrap();
31///
32/// println!("{process_status:#?}");
33/// ```
34pub fn get_process_status(pid: u32) -> Result<ProcessStatus, ScannerError> {
35    let mut status = ProcessStatus::default();
36
37    let status_path = Path::new("/proc").join(pid.to_string()).join("status");
38
39    let mut sc: ScannerAscii<_, U192> = ScannerAscii::scan_path2(status_path)?;
40
41    loop {
42        let label = sc.next_raw()?.ok_or(ErrorKind::UnexpectedEof)?;
43
44        if label.starts_with(b"Uid") {
45            status.real_uid = sc.next_u32()?.ok_or(ErrorKind::UnexpectedEof)?;
46            status.effective_uid = sc.next_u32()?.ok_or(ErrorKind::UnexpectedEof)?;
47            status.saved_set_uid = sc.next_u32()?.ok_or(ErrorKind::UnexpectedEof)?;
48            status.fs_uid = sc.next_u32()?.ok_or(ErrorKind::UnexpectedEof)?;
49
50            break;
51        } else {
52            sc.drop_next_line()?.ok_or(ErrorKind::UnexpectedEof)?;
53        }
54    }
55
56    loop {
57        let label = sc.next_raw()?.ok_or(ErrorKind::UnexpectedEof)?;
58
59        if label.starts_with(b"Gid") {
60            status.real_gid = sc.next_u32()?.ok_or(ErrorKind::UnexpectedEof)?;
61            status.effective_gid = sc.next_u32()?.ok_or(ErrorKind::UnexpectedEof)?;
62            status.saved_set_gid = sc.next_u32()?.ok_or(ErrorKind::UnexpectedEof)?;
63            status.fs_gid = sc.next_u32()?.ok_or(ErrorKind::UnexpectedEof)?;
64
65            break;
66        } else {
67            sc.drop_next_line()?.ok_or(ErrorKind::UnexpectedEof)?;
68        }
69    }
70
71    Ok(status)
72}