Improve /proc/{PID}/stat

This commit is contained in:
lab-pc-wtj
2024-12-17 20:10:31 +08:00
committed by Tate, Hongliang Tian
parent 776fd6a892
commit 6e4a4c58d0

View File

@ -8,7 +8,6 @@ use crate::{
utils::Inode,
},
prelude::*,
process::posix_thread::AsPosixThread,
Process,
};
@ -16,6 +15,59 @@ use crate::{
/// The fields are the same as the ones in `/proc/[pid]/status`. But the format is different.
/// See https://github.com/torvalds/linux/blob/ce1c54fdff7c4556b08f5b875a331d8952e8b6b7/fs/proc/array.c#L467
/// FIXME: Some fields are not implemented yet.
///
/// Fields:
/// - pid : Process ID.
/// - comm : Process name.
/// - state : Process state (R: running, S: sleeping, Z: zombie).
/// - ppid : Parent process ID.
/// - pgrp : Process group ID.
/// - session : Session ID.
/// - tty_nr : Terminal associated with the process.
/// - tpgid : Foreground process group ID.
/// - flags : Kernel flags determining process behavior.
/// - minflt : Minor page faults (no I/O needed).
/// - cminflt : Cumulative minor faults of child processes.
/// - majflt : Major page faults (I/O required).
/// - cmajflt : Cumulative major faults of child processes.
/// - utime : Time spent in user mode (clock ticks).
/// - stime : Time spent in kernel mode (clock ticks).
/// - cutime : Child processes' user mode time.
/// - cstime : Child processes' kernel mode time.
/// - priority : Process priority or nice value.
/// - nice : Nice value (-20 to 19; lower is higher priority).
/// - num_threads : Number of threads.
/// - starttime : Process start time since boot (clock ticks).
/// - vsize : Virtual memory size (bytes).
/// - rss : Resident Set Size (pages in real memory).
/// - rsslim : Soft memory limit (bytes).
/// - startcode : Start address of executable code.
/// - endcode : End address of executable code.
/// - startstack : Bottom address of process stack.
/// - kstkesp : Current stack pointer (ESP).
/// - kstkeip : Current instruction pointer (EIP).
/// - signal : Bitmap of pending signals.
/// - blocked : Bitmap of blocked signals.
/// - sigignore : Bitmap of ignored signals.
/// - sigcatch : Bitmap of caught signals.
/// - wchan : Address where the process is waiting.
/// - nswap : Number of pages swapped (deprecated).
/// - cnswap : Cumulative swapped pages of children.
/// - exit_signal : Signal sent to parent on termination.
/// - processor : Last CPU the process executed on.
/// - rt_priority : Real-time scheduling priority (1-99, 0 otherwise).
/// - policy : Scheduling policy (e.g., SCHED_NORMAL, SCHED_FIFO).
/// - delayacct_blkio_ticks : Block I/O delays (clock ticks).
/// - guest_time : Time spent as a guest in virtual CPU.
/// - cguest_time : Guest time of child processes.
/// - start_data : Start address of initialized/uninitialized data.
/// - end_data : End address of initialized/uninitialized data.
/// - start_brk : Address above which the heap expands.
/// - arg_start : Start address of command-line arguments.
/// - arg_end : End address of command-line arguments.
/// - env_start : Start address of environment variables.
/// - env_end : End address of environment variables.
/// - exit_code : Process exit code as returned by waitpid(2).
pub struct StatFileOps(Arc<Process>);
impl StatFileOps {
@ -30,20 +82,26 @@ impl StatFileOps {
impl FileOps for StatFileOps {
fn data(&self) -> Result<Vec<u8>> {
let process = &self.0;
let main_thread = process.main_thread();
let file_table = main_thread.as_posix_thread().unwrap().file_table();
let pid = process.pid();
let comm = process.executable_path();
let ppid = process.parent().pid();
let state = if process.status().is_zombie() {
'Z'
} else {
'R'
};
let pgrp = if let Some(pgrp) = process.process_group() {
pgrp.pgid()
} else {
0
};
let mut stat_output = String::new();
writeln!(
stat_output,
"{} {} {} {} {} {} {}",
process.executable_path(),
process.pid(),
process.pid(),
process.parent().pid(),
process.parent().pid(),
file_table.lock().len(),
process.tasks().lock().as_slice().len(),
"{} ({}) {} {} {}",
pid, comm, state, ppid, pgrp
)
.unwrap();
Ok(stat_output.into_bytes())