pstree: lots of fiddling and learning the language

I think I'm starting to 'get it' a bit more.  Rust really forces the
issue with dealing with error types and you kind of need to get deep
into all parts of the language right away to get stuff working; that
being said, the language is reasonable in size and has a relatively
small number of concepts.
This commit is contained in:
Paul Osborne 2014-10-11 02:58:12 -05:00
parent 76204e72df
commit b1fa5a4d58

View file

@ -31,38 +31,54 @@ use std::io::fs::PathExtensions;
use std::io::fs; use std::io::fs;
use std::io::File; use std::io::File;
use std::io::BufferedReader; use std::io::BufferedReader;
use std::collections::hashmap::HashMap; use std::fmt;
struct ProcessRecord {
name: String,
pid: int,
ppid: int
}
impl fmt::Show for ProcessRecord {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "ProcessRecord [ name: {}, pid: {}, ppid: {} )",
self.name,
self.pid,
self.ppid)
}
}
// Given a status file path, return a hashmap with the following form:
// pid -> ProcessRecord
fn get_status_info(status_path: &Path) -> Option<ProcessRecord> {
let mut pid : Option<int> = None;
let mut ppid : Option<int> = None;
let mut name : Option<String> = None;
fn process_status_file(status_path: &Path) {
let mut status_file = BufferedReader::new(File::open(status_path)); let mut status_file = BufferedReader::new(File::open(status_path));
let mut status_data = HashMap::new();
for line in status_file.lines() { for line in status_file.lines() {
let linetext = match line { let unwrapped = line.unwrap(); // need a new lifeline
Err(why) => fail!("{}", why.desc), let parts : Vec<&str> = unwrapped.as_slice().splitn(2, ':').collect();
Ok(l) => l
};
let parts: Vec<&str> = linetext.as_slice().splitn(2, ':').collect();
if parts.len() == 2 { if parts.len() == 2 {
let key = parts[0].trim(); let key = parts[0].trim();
let value = parts[1].trim(); let value = parts[1].trim();
status_data.insert(key.to_string(), value.to_string()); match key {
}; "Name" => name = Some(value.to_string()),
"Pid" => pid = from_str(value),
"PPid" => ppid = from_str(value),
_ => (),
}
}
} }
let name_key = &("Name".to_string()); return if pid.is_some() && ppid.is_some() && name.is_some() {
let pid_key = &("Pid".to_string()); Some(ProcessRecord { name: name.unwrap(), pid: pid.unwrap(), ppid: ppid.unwrap() })
let ppid_key = &("PPid".to_string()); } else {
None
if status_data.contains_key(name_key) && }
status_data.contains_key(pid_key) &&
status_data.contains_key(ppid_key) {
println!("{}#{} -> {}",
status_data.get(name_key),
status_data.get(pid_key),
status_data.get(ppid_key));
}
} }
fn dump_process_info() { fn dump_process_info() {
let proc_directory = Path::new("/proc"); let proc_directory = Path::new("/proc");
let proc_directory_contents = match fs::readdir(&proc_directory) { let proc_directory_contents = match fs::readdir(&proc_directory) {
@ -73,7 +89,11 @@ fn dump_process_info() {
if entry.is_dir() { if entry.is_dir() {
let status_path = entry.join("status"); let status_path = entry.join("status");
if status_path.exists() { if status_path.exists() {
process_status_file(&status_path); let record = get_status_info(&status_path);
match record {
Some(record) => println!("{}", record),
None => ()
}
} }
} }
} }