diff --git a/userspace/sysutils/Cargo.toml b/userspace/sysutils/Cargo.toml index 0f3f7d8d..9b17d251 100644 --- a/userspace/sysutils/Cargo.toml +++ b/userspace/sysutils/Cargo.toml @@ -133,6 +133,10 @@ path = "src/sleep.rs" name = "lspci" path = "src/lspci.rs" +[[bin]] +name = "ps" +path = "src/ps.rs" + [[bin]] name = "tst" path = "src/tst.rs" diff --git a/userspace/sysutils/src/ps.rs b/userspace/sysutils/src/ps.rs new file mode 100644 index 00000000..b47d89e9 --- /dev/null +++ b/userspace/sysutils/src/ps.rs @@ -0,0 +1,60 @@ +use std::{fs, io, path::PathBuf, process::ExitCode}; + +#[derive(Debug)] +struct ProcessInfo { + pid: u32, + name: String, +} + +fn list_processes() -> io::Result> { + let mut list = vec![]; + for entry in fs::read_dir("/sys/proc")? { + let Ok(entry) = entry else { + continue; + }; + let filename = entry.file_name(); + let Some(name) = filename.to_str() else { + continue; + }; + let Ok(pid) = name.parse() else { + continue; + }; + list.push(pid); + } + Ok(list) +} + +fn process_info(pid: u32) -> io::Result { + let base = PathBuf::from("/sys/proc").join(format!("{pid}")); + let name = fs::read_to_string(base.join("name"))?; + Ok(ProcessInfo { pid, name }) +} + +fn processes() -> io::Result> { + let pids = list_processes()?; + let processes = pids + .into_iter() + .filter_map(|pid| process_info(pid).ok()) + .collect(); + Ok(processes) +} + +fn run() -> io::Result<()> { + let mut processes = processes()?; + processes.sort_by(|a, b| Ord::cmp(&a.pid, &b.pid)); + println!("{:>4} NAME", "PID"); + for process in processes { + println!("{:4} {}", process.pid, process.name.trim()); + } + Ok(()) +} + +fn main() -> ExitCode { + match run() { + Ok(()) => ExitCode::SUCCESS, + Err(error) => { + eprintln!("{error}"); + ExitCode::FAILURE + } + } +} diff --git a/xtask/src/build/userspace.rs b/xtask/src/build/userspace.rs index 41ddf620..4fe227c9 100644 --- a/xtask/src/build/userspace.rs +++ b/xtask/src/build/userspace.rs @@ -48,6 +48,7 @@ const PROGRAMS: &[(&str, &str)] = &[ ("sync", "bin/sync"), ("sleep", "bin/sleep"), ("lspci", "bin/lspci"), + ("ps", "bin/ps"), ("tst", "bin/tst"), // netutils ("netconf", "sbin/netconf"),