Files
rsnmpagent/src/rsnmplib/processes.rs
2025-12-23 11:11:26 +01:00

74 lines
3.2 KiB
Rust

use log::{debug, error, trace, warn};
use serde::{Deserialize, Serialize};
use std::fs;
use std::io;
use std::path::Path;
#[derive(Deserialize, Serialize, Debug, Default)]
pub(crate) struct Ptypes {
pub(crate) running: u32, // R => Running
pub(crate) sleeping: u32, // S => Sleeping in an interruptible wait
pub(crate) waiting: u32, // D => Waiting in uninterruptible disk sleep
pub(crate) zombie: u32, // Z => Zombie
pub(crate) stopped: u32, // T => Stopped (on a signal) or (before Linux 2.6.33) trace stopped
pub(crate) stop: u32, // t => tracing stop (Linux 2.6.33 onward)
//pub(crate) paging: u64, // W => Paging (only before Linux 2.6.0)
pub(crate) dead: u32, // X => Dead (from Linux 2.6.0 onward) or x => Dead (Linux 2.6.33 to 3.13 only)
pub(crate) wakekill: u32, // K => Wakekill (Linux 2.6.33 to 3.13 only)
pub(crate) waking: u32, // W => Waking (Linux 2.6.33 to 3.13 only)
pub(crate) idle: u32, // I => Idle (Linux 4.14 onward)
}
pub(crate) fn count_processes(proc_path: &Path) -> io::Result<Ptypes> {
let mut counts = Ptypes::default();
debug!("Staring count_processes, iterating over {:?}", proc_path);
for entry_result in fs::read_dir(proc_path)? {
let entry = entry_result?;
let path = entry.path();
// Check if the directory name is a number (a PID)
if path.is_dir()
&& path
.file_name()
.and_then(|s| s.to_str())
.unwrap_or("")
.parse::<u32>()
.is_ok()
{
let stat_path = path.join("stat");
trace!("now reading contents of {:?}", stat_path);
if let Ok(stat_contents) = fs::read_to_string(&stat_path) {
// Read whole file, we read from memory, so we can search ")" from behind.
if let Some(pos) = stat_contents.rfind(")") {
match stat_contents.as_bytes().get(pos + 2) {
Some(&byteval) => {
match byteval {
82 => counts.running += 1, // R
83 => counts.sleeping += 1, // S
68 => counts.waiting += 1, // D
84 => counts.stopped += 1, // T
116 => counts.stop += 1, // t
//87 => counts.paging += 1, // W --> only before 2.6 !!
88 => counts.dead += 1, // X
120 => counts.dead += 1, // x
75 => counts.wakekill += 1, // K
87 => counts.waking += 1, // W
73 => counts.idle += 1, // I
_ => warn!("unknown proc status value {}", byteval),
}
}
None => {
error!("Problem parsing stat data {}", stat_contents);
}
}
}
} else {
error!("read_to_string failed for {:?}", stat_path);
}
}
}
Ok(counts)
}