mirror of
https://github.com/posborne/rust-pstree.git
synced 2024-12-27 07:26:03 +01:00
Move to the new std::io APIs for parsing proc files
The implementation is certainly not cleaner to look at. For whatever reason, the noticeable delay that was present on startup previously is now gone, so some performance issue must have been resolved with this change as well.
This commit is contained in:
parent
8d9bf2cefb
commit
99b4bdd596
1 changed files with 33 additions and 24 deletions
57
pstree.rs
57
pstree.rs
|
@ -27,14 +27,15 @@
|
||||||
// of different items, notably the process name and its parent process id (ppid).
|
// of different items, notably the process name and its parent process id (ppid).
|
||||||
// And with that information, we can build the process tree.
|
// And with that information, we can build the process tree.
|
||||||
|
|
||||||
#![feature(old_io)]
|
|
||||||
#![feature(old_path)]
|
|
||||||
#![feature(std_misc)] // hash_map::Entry
|
#![feature(std_misc)] // hash_map::Entry
|
||||||
|
#![feature(path)]
|
||||||
|
#![feature(fs)]
|
||||||
|
#![feature(io)]
|
||||||
|
|
||||||
use std::old_io::fs::PathExtensions;
|
use std::path::Path;
|
||||||
use std::old_io::fs;
|
use std::fs;
|
||||||
use std::old_io::File;
|
use std::io::prelude::*;
|
||||||
use std::old_io::BufferedReader;
|
use std::fs::File;
|
||||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
@ -71,22 +72,29 @@ fn get_process_record(status_path: &Path) -> Option<ProcessRecord> {
|
||||||
let mut ppid : Option<i32> = None;
|
let mut ppid : Option<i32> = None;
|
||||||
let mut name : Option<String> = None;
|
let mut name : Option<String> = None;
|
||||||
|
|
||||||
let mut status_file = BufferedReader::new(File::open(status_path));
|
let mut reader = std::io::BufReader::new(File::open(status_path).unwrap());
|
||||||
for line in status_file.lines() {
|
loop {
|
||||||
let unwrapped = line.unwrap(); // need a new lifeline
|
let mut linebuf = String::new();
|
||||||
let parts : Vec<&str> = unwrapped[..].splitn(2, ':').collect();
|
match reader.read_line(&mut linebuf) {
|
||||||
if parts.len() == 2 {
|
Ok(_) => {
|
||||||
let key = parts[0].trim();
|
if linebuf.is_empty() {
|
||||||
let value = parts[1].trim();
|
break;
|
||||||
match key {
|
}
|
||||||
"Name" => name = Some(value.to_string()),
|
let parts : Vec<&str> = linebuf[..].splitn(2, ':').collect();
|
||||||
"Pid" => pid = value.parse().ok(),
|
if parts.len() == 2 {
|
||||||
"PPid" => ppid = value.parse().ok(),
|
let key = parts[0].trim();
|
||||||
_ => (),
|
let value = parts[1].trim();
|
||||||
}
|
match key {
|
||||||
|
"Name" => name = Some(value.to_string()),
|
||||||
|
"Pid" => pid = value.parse().ok(),
|
||||||
|
"PPid" => ppid = value.parse().ok(),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return if pid.is_some() && ppid.is_some() && name.is_some() {
|
return if pid.is_some() && ppid.is_some() && name.is_some() {
|
||||||
Some(ProcessRecord { name: name.unwrap(), pid: pid.unwrap(), ppid: ppid.unwrap() })
|
Some(ProcessRecord { name: name.unwrap(), pid: pid.unwrap(), ppid: ppid.unwrap() })
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,10 +108,11 @@ fn get_process_records() -> Vec<ProcessRecord> {
|
||||||
let proc_directory = Path::new("/proc");
|
let proc_directory = Path::new("/proc");
|
||||||
|
|
||||||
// find potential process directories under /proc
|
// find potential process directories under /proc
|
||||||
let proc_directory_contents = fs::readdir(&proc_directory).unwrap();
|
let proc_directory_contents = fs::read_dir(&proc_directory).unwrap();
|
||||||
proc_directory_contents.iter().filter_map(|entry| {
|
proc_directory_contents.filter_map(|entry| {
|
||||||
if entry.is_dir() {
|
let entry_path = entry.unwrap().path();
|
||||||
let status_path = entry.join("status");
|
if entry_path.is_dir() {
|
||||||
|
let status_path = entry_path.join("status");
|
||||||
if status_path.exists() {
|
if status_path.exists() {
|
||||||
return get_process_record(&status_path)
|
return get_process_record(&status_path)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue