Skip to content

Commit

Permalink
Fix breakage introduced by #887 (#890)
Browse files Browse the repository at this point in the history
  • Loading branch information
squell authored Oct 22, 2024
2 parents 273c317 + 5cecdf8 commit f70da0f
Showing 1 changed file with 23 additions and 4 deletions.
27 changes: 23 additions & 4 deletions src/system/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ impl Process {
/// attached to the given process
pub fn tty_device_id(pid: WithProcess) -> std::io::Result<Option<DeviceId>> {
// device id of tty is displayed as a signed integer of 32 bits
let data: i32 = read_proc_stat(pid, 7 /* tty_nr */)?;
let data: i32 = read_proc_stat(pid, 6 /* tty_nr */)?;
if data == 0 {
Ok(None)
} else {
Expand All @@ -615,7 +615,7 @@ impl Process {

/// Get the process starting time of a specific process
pub fn starting_time(pid: WithProcess) -> io::Result<SystemTime> {
let process_start: u64 = read_proc_stat(pid, 22 /* start_time */)?;
let process_start: u64 = read_proc_stat(pid, 21 /* start_time */)?;

// the startime field is stored in ticks since the system start, so we need to know how many
// ticks go into a second
Expand All @@ -634,13 +634,19 @@ impl Process {
}
}

/// Read the n-th field (with 1-based indexing) from `/proc/<pid>/self`.
/// Read the n-th field (with 0-based indexing) from `/proc/<pid>/self`.
///
/// See ["Table 1-4: Contents of the stat fields" of "The /proc
/// Filesystem"][proc_stat_fields] in the Linux docs for all available fields.
///
/// IMPORTANT: the first two fields are not accessible with this routine.
///
/// [proc_stat_fields]: https://www.kernel.org/doc/html/latest/filesystems/proc.html#id10
fn read_proc_stat<T: FromStr>(pid: WithProcess, field_idx: isize) -> io::Result<T> {
// the first two fields are skipped by the code below, and we never need them,
// so no point in implementing code for it in this private function.
debug_assert!(field_idx >= 2);

// read from a specific pid file, or use `self` to refer to our own process
let pidref = pid.to_proc_string();

Expand All @@ -661,7 +667,7 @@ fn read_proc_stat<T: FromStr>(pid: WithProcess, field_idx: isize) -> io::Result<
// we've now passed the first two fields, so we are at index 1, now we skip over
// fields until we arrive at the field we are searching for
let mut curr_field = 1;
while curr_field <= field_idx && !stat.is_empty() {
while curr_field < field_idx && !stat.is_empty() {
if stat[0] == b' ' {
curr_field += 1;
}
Expand Down Expand Up @@ -960,4 +966,17 @@ mod tests {
let (_, status) = child_pid.wait(WaitOptions::new()).unwrap();
assert_eq!(status.exit_status(), Some(0));
}

#[cfg(target_os = "linux")]
#[test]
fn proc_stat_test() {
use super::{read_proc_stat, Process, WithProcess::Current};
// the process is 'sleeping' (apparently)
assert_eq!("S", read_proc_stat::<String>(Current, 2).unwrap());
let parent = Process::parent_id().unwrap();
// field 3 is always the parent process
assert_eq!(parent, read_proc_stat::<i32>(Current, 3).unwrap());
// this next field should always be 0 (which precedes an important bit of info for us!)
assert_eq!(0, read_proc_stat::<i32>(Current, 20).unwrap());
}
}

0 comments on commit f70da0f

Please sign in to comment.