mirror of
https://github.com/posborne/rust-pstree.git
synced 2025-03-04 06:34:40 +01:00
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:
parent
76204e72df
commit
b1fa5a4d58
1 changed files with 43 additions and 23 deletions
66
pstree.rs
66
pstree.rs
|
@ -31,38 +31,54 @@ use std::io::fs::PathExtensions;
|
|||
use std::io::fs;
|
||||
use std::io::File;
|
||||
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_data = HashMap::new();
|
||||
for line in status_file.lines() {
|
||||
let linetext = match line {
|
||||
Err(why) => fail!("{}", why.desc),
|
||||
Ok(l) => l
|
||||
};
|
||||
let parts: Vec<&str> = linetext.as_slice().splitn(2, ':').collect();
|
||||
let unwrapped = line.unwrap(); // need a new lifeline
|
||||
let parts : Vec<&str> = unwrapped.as_slice().splitn(2, ':').collect();
|
||||
if parts.len() == 2 {
|
||||
let key = parts[0].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());
|
||||
let pid_key = &("Pid".to_string());
|
||||
let ppid_key = &("PPid".to_string());
|
||||
|
||||
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));
|
||||
}
|
||||
return if pid.is_some() && ppid.is_some() && name.is_some() {
|
||||
Some(ProcessRecord { name: name.unwrap(), pid: pid.unwrap(), ppid: ppid.unwrap() })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn dump_process_info() {
|
||||
let proc_directory = Path::new("/proc");
|
||||
let proc_directory_contents = match fs::readdir(&proc_directory) {
|
||||
|
@ -73,7 +89,11 @@ fn dump_process_info() {
|
|||
if entry.is_dir() {
|
||||
let status_path = entry.join("status");
|
||||
if status_path.exists() {
|
||||
process_status_file(&status_path);
|
||||
let record = get_status_info(&status_path);
|
||||
match record {
|
||||
Some(record) => println!("{}", record),
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue