rust-pstree/pstree.rs

194 lines
6.5 KiB
Rust
Raw Normal View History

// A version of pstree targetting linux written in rust!
//
// This is based on the following exercise from the excellent
// book "The Linux Programming Interface" by Michael Kerridsk.
//
//----------------------------------------------------------------------
//
// Write a program that draws a tree showing the hierarchical
// parent-child relationships of all processes on the system, going all
// the way back to init. For each process, the program should display
// the process ID and the command being executed. The output of the
// program should be similar to that produced by pstree(1), although it
// does need not to be as sophisticated. The parent of each process on
// the system can be found by inspecing the PPid: line of all of the
// /proc/PID/status files on the system. Be careful to handle the
// possibilty that a process's parent (and thus its /proc/PID directory)
// disappears during the scan of all /proc/PID directories.
// Implementation Notes
// --------------------
// The linux /proc filesystem is a virtual filesystem that provides information
// about processes running on a linux system among other things. The /proc
// filesystem contains a directory, /proc/<pid>, for each running process in
// the system.
//
// Each process directory has a status file with contents including a bunch
// of different items, notably the process name and its parent process id (ppid).
// And with that information, we can build the process tree.
#![feature(std_misc)] // hash_map::Entry
#![feature(path)]
#![feature(fs)]
#![feature(io)]
use std::path::Path;
use std::fs;
use std::io::prelude::*;
use std::fs::File;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::HashMap;
#[derive(Clone,Debug)]
struct ProcessRecord {
name: String,
pid: i32,
ppid: i32,
}
#[derive(Clone,Debug)]
pstree: It works... it actually works! Lots of learning along the way and realizations that Rust's manual memory management actually prevents you from doing bad things that you might otherwise want to do. Fair enough. Lots of syntactic struggles and wishin the language was managed at times. - / #0 - init #1 - upstart-udev-br #295 - systemd-udevd #303 - upstart-file-br #391 - rsyslogd #443 - dbus-daemon #499 - upstart-socket- #507 - ModemManager #579 - bluetoothd #581 - systemd-logind #593 - avahi-daemon #686 - avahi-daemon #688 - NetworkManager #777 - dhclient #1046 - dnsmasq #1060 - getty #859 - getty #863 - polkitd #899 - getty #904 - getty #905 - getty #908 - sh #931 - initctl #944 - sshd #981 - kerneloops #1000 - cron #1006 - acpid #1018 - cups-browsed #1023 - whoopsie #1054 - VBoxService #1210 - getty #1276 - lightdm #1295 - Xorg #1319 - lightdm #1340 - mate-session #1355 - ssh-agent #1446 - mate-settings-d #1541 - marco #1545 - zenity #8779 - mate-panel #1549 - mate-terminal #1864 - gnome-pty-helpe #1873 - zsh #1874 - pstree #15186 - emacs #13667 - pstree #15186 - zsh #7803 - java #8648 - caja #1558 - polkit-mate-aut #1587 - deja-dup-monito #1589 - indicator-power #1593 - indicator-bluet #1594 - update-notifier #1600 - zeitgeist-datah #1607 - nm-applet #1613 - applet.py #1623 - accounts-daemon #1305 - VBoxClient #1423 - VBoxClient #1431 - VBoxClient #1436 - VBoxClient #1441 - dbus-launch #1450 - dbus-daemon #1461 - ibus-daemon #1476 - ibus-dconf #1493 - ibus-ui-gtk3 #1494 - ibus-engine-sim #1570 - gvfsd #1488 - ibus-x11 #1498 - gvfsd-fuse #1503 - dconf-service #1509 - gnome-keyring-d #1522 - at-spi-bus-laun #1528 - dbus-daemon #1532 - at-spi2-registr #1535 - pulseaudio #1561 - rtkit-daemon #1563 - gvfs-udisks2-vo #1572 - udisksd #1581 - upowerd #1599 - gvfs-mtp-volume #1630 - zeitgeist-daemo #1634 - gvfs-gphoto2-vo #1639 - gvfs-afc-volume #1671 - zeitgeist-fts #1708 - cat #1789 - wnck-applet #1767 - notification-ar #1769 - clock-applet #1771 - gvfsd-trash #1792 - gconfd-2 #1798 - cupsd #1858 - gvfsd-burn #8225 - geoclue-master #8247 - ubuntu-geoip-pr #8251 - gvfsd-http #8281 - master #11380 - qmgr #11383 - pickup #13717 - notify-osd #11677 - gnome-screensav #11715 - gvfsd-metadata #13196 - oneconf-service #15144 - kthreadd #2 - ksoftirqd/0 #3 - rcu_sched #7 - rcuos/0 #8 - rcuos/1 #9 - rcu_bh #10 - rcuob/0 #11 - rcuob/1 #12 - migration/0 #13 - watchdog/0 #14 - watchdog/1 #15 - migration/1 #16 - ksoftirqd/1 #17 - khelper #20 - kdevtmpfs #21 - netns #22 - writeback #23 - kintegrityd #24 - bioset #25 - kblockd #27 - ata_sff #28 - khubd #29 - md #30 - devfreq_wq #31 - khungtaskd #33 - kswapd0 #34 - ksmd #35 - khugepaged #36 - fsnotify_mark #37 - ecryptfs-kthrea #38 - crypto #39 - kthrotld #51 - scsi_eh_0 #54 - scsi_eh_1 #55 - deferwq #76 - charger_manager #77 - scsi_eh_2 #118 - kpsmoused #122 - kdmflush #138 - bioset #139 - kdmflush #140 - bioset #141 - jbd2/dm-0-8 #157 - ext4-rsv-conver #158 - ext4-rsv-conver #341 - iprt #422 - krfcommd #694 - kauditd #1345
2014-10-14 10:57:18 +02:00
struct ProcessTreeNode {
record: ProcessRecord, // the node owns the associated record
children: Vec<ProcessTreeNode>, // nodes own their children
}
#[derive(Clone,Debug)]
pstree: It works... it actually works! Lots of learning along the way and realizations that Rust's manual memory management actually prevents you from doing bad things that you might otherwise want to do. Fair enough. Lots of syntactic struggles and wishin the language was managed at times. - / #0 - init #1 - upstart-udev-br #295 - systemd-udevd #303 - upstart-file-br #391 - rsyslogd #443 - dbus-daemon #499 - upstart-socket- #507 - ModemManager #579 - bluetoothd #581 - systemd-logind #593 - avahi-daemon #686 - avahi-daemon #688 - NetworkManager #777 - dhclient #1046 - dnsmasq #1060 - getty #859 - getty #863 - polkitd #899 - getty #904 - getty #905 - getty #908 - sh #931 - initctl #944 - sshd #981 - kerneloops #1000 - cron #1006 - acpid #1018 - cups-browsed #1023 - whoopsie #1054 - VBoxService #1210 - getty #1276 - lightdm #1295 - Xorg #1319 - lightdm #1340 - mate-session #1355 - ssh-agent #1446 - mate-settings-d #1541 - marco #1545 - zenity #8779 - mate-panel #1549 - mate-terminal #1864 - gnome-pty-helpe #1873 - zsh #1874 - pstree #15186 - emacs #13667 - pstree #15186 - zsh #7803 - java #8648 - caja #1558 - polkit-mate-aut #1587 - deja-dup-monito #1589 - indicator-power #1593 - indicator-bluet #1594 - update-notifier #1600 - zeitgeist-datah #1607 - nm-applet #1613 - applet.py #1623 - accounts-daemon #1305 - VBoxClient #1423 - VBoxClient #1431 - VBoxClient #1436 - VBoxClient #1441 - dbus-launch #1450 - dbus-daemon #1461 - ibus-daemon #1476 - ibus-dconf #1493 - ibus-ui-gtk3 #1494 - ibus-engine-sim #1570 - gvfsd #1488 - ibus-x11 #1498 - gvfsd-fuse #1503 - dconf-service #1509 - gnome-keyring-d #1522 - at-spi-bus-laun #1528 - dbus-daemon #1532 - at-spi2-registr #1535 - pulseaudio #1561 - rtkit-daemon #1563 - gvfs-udisks2-vo #1572 - udisksd #1581 - upowerd #1599 - gvfs-mtp-volume #1630 - zeitgeist-daemo #1634 - gvfs-gphoto2-vo #1639 - gvfs-afc-volume #1671 - zeitgeist-fts #1708 - cat #1789 - wnck-applet #1767 - notification-ar #1769 - clock-applet #1771 - gvfsd-trash #1792 - gconfd-2 #1798 - cupsd #1858 - gvfsd-burn #8225 - geoclue-master #8247 - ubuntu-geoip-pr #8251 - gvfsd-http #8281 - master #11380 - qmgr #11383 - pickup #13717 - notify-osd #11677 - gnome-screensav #11715 - gvfsd-metadata #13196 - oneconf-service #15144 - kthreadd #2 - ksoftirqd/0 #3 - rcu_sched #7 - rcuos/0 #8 - rcuos/1 #9 - rcu_bh #10 - rcuob/0 #11 - rcuob/1 #12 - migration/0 #13 - watchdog/0 #14 - watchdog/1 #15 - migration/1 #16 - ksoftirqd/1 #17 - khelper #20 - kdevtmpfs #21 - netns #22 - writeback #23 - kintegrityd #24 - bioset #25 - kblockd #27 - ata_sff #28 - khubd #29 - md #30 - devfreq_wq #31 - khungtaskd #33 - kswapd0 #34 - ksmd #35 - khugepaged #36 - fsnotify_mark #37 - ecryptfs-kthrea #38 - crypto #39 - kthrotld #51 - scsi_eh_0 #54 - scsi_eh_1 #55 - deferwq #76 - charger_manager #77 - scsi_eh_2 #118 - kpsmoused #122 - kdmflush #138 - bioset #139 - kdmflush #140 - bioset #141 - jbd2/dm-0-8 #157 - ext4-rsv-conver #158 - ext4-rsv-conver #341 - iprt #422 - krfcommd #694 - kauditd #1345
2014-10-14 10:57:18 +02:00
struct ProcessTree {
root: ProcessTreeNode, // tree owns ref to root node
}
impl ProcessTreeNode {
// constructor
fn new(record : &ProcessRecord) -> ProcessTreeNode {
ProcessTreeNode { record: (*record).clone(), children: Vec::new() }
}
}
pstree: It works... it actually works! Lots of learning along the way and realizations that Rust's manual memory management actually prevents you from doing bad things that you might otherwise want to do. Fair enough. Lots of syntactic struggles and wishin the language was managed at times. - / #0 - init #1 - upstart-udev-br #295 - systemd-udevd #303 - upstart-file-br #391 - rsyslogd #443 - dbus-daemon #499 - upstart-socket- #507 - ModemManager #579 - bluetoothd #581 - systemd-logind #593 - avahi-daemon #686 - avahi-daemon #688 - NetworkManager #777 - dhclient #1046 - dnsmasq #1060 - getty #859 - getty #863 - polkitd #899 - getty #904 - getty #905 - getty #908 - sh #931 - initctl #944 - sshd #981 - kerneloops #1000 - cron #1006 - acpid #1018 - cups-browsed #1023 - whoopsie #1054 - VBoxService #1210 - getty #1276 - lightdm #1295 - Xorg #1319 - lightdm #1340 - mate-session #1355 - ssh-agent #1446 - mate-settings-d #1541 - marco #1545 - zenity #8779 - mate-panel #1549 - mate-terminal #1864 - gnome-pty-helpe #1873 - zsh #1874 - pstree #15186 - emacs #13667 - pstree #15186 - zsh #7803 - java #8648 - caja #1558 - polkit-mate-aut #1587 - deja-dup-monito #1589 - indicator-power #1593 - indicator-bluet #1594 - update-notifier #1600 - zeitgeist-datah #1607 - nm-applet #1613 - applet.py #1623 - accounts-daemon #1305 - VBoxClient #1423 - VBoxClient #1431 - VBoxClient #1436 - VBoxClient #1441 - dbus-launch #1450 - dbus-daemon #1461 - ibus-daemon #1476 - ibus-dconf #1493 - ibus-ui-gtk3 #1494 - ibus-engine-sim #1570 - gvfsd #1488 - ibus-x11 #1498 - gvfsd-fuse #1503 - dconf-service #1509 - gnome-keyring-d #1522 - at-spi-bus-laun #1528 - dbus-daemon #1532 - at-spi2-registr #1535 - pulseaudio #1561 - rtkit-daemon #1563 - gvfs-udisks2-vo #1572 - udisksd #1581 - upowerd #1599 - gvfs-mtp-volume #1630 - zeitgeist-daemo #1634 - gvfs-gphoto2-vo #1639 - gvfs-afc-volume #1671 - zeitgeist-fts #1708 - cat #1789 - wnck-applet #1767 - notification-ar #1769 - clock-applet #1771 - gvfsd-trash #1792 - gconfd-2 #1798 - cupsd #1858 - gvfsd-burn #8225 - geoclue-master #8247 - ubuntu-geoip-pr #8251 - gvfsd-http #8281 - master #11380 - qmgr #11383 - pickup #13717 - notify-osd #11677 - gnome-screensav #11715 - gvfsd-metadata #13196 - oneconf-service #15144 - kthreadd #2 - ksoftirqd/0 #3 - rcu_sched #7 - rcuos/0 #8 - rcuos/1 #9 - rcu_bh #10 - rcuob/0 #11 - rcuob/1 #12 - migration/0 #13 - watchdog/0 #14 - watchdog/1 #15 - migration/1 #16 - ksoftirqd/1 #17 - khelper #20 - kdevtmpfs #21 - netns #22 - writeback #23 - kintegrityd #24 - bioset #25 - kblockd #27 - ata_sff #28 - khubd #29 - md #30 - devfreq_wq #31 - khungtaskd #33 - kswapd0 #34 - ksmd #35 - khugepaged #36 - fsnotify_mark #37 - ecryptfs-kthrea #38 - crypto #39 - kthrotld #51 - scsi_eh_0 #54 - scsi_eh_1 #55 - deferwq #76 - charger_manager #77 - scsi_eh_2 #118 - kpsmoused #122 - kdmflush #138 - bioset #139 - kdmflush #140 - bioset #141 - jbd2/dm-0-8 #157 - ext4-rsv-conver #158 - ext4-rsv-conver #341 - iprt #422 - krfcommd #694 - kauditd #1345
2014-10-14 10:57:18 +02:00
// Given a status file path, return a hashmap with the following form:
// pid -> ProcessRecord
pstree: It works... it actually works! Lots of learning along the way and realizations that Rust's manual memory management actually prevents you from doing bad things that you might otherwise want to do. Fair enough. Lots of syntactic struggles and wishin the language was managed at times. - / #0 - init #1 - upstart-udev-br #295 - systemd-udevd #303 - upstart-file-br #391 - rsyslogd #443 - dbus-daemon #499 - upstart-socket- #507 - ModemManager #579 - bluetoothd #581 - systemd-logind #593 - avahi-daemon #686 - avahi-daemon #688 - NetworkManager #777 - dhclient #1046 - dnsmasq #1060 - getty #859 - getty #863 - polkitd #899 - getty #904 - getty #905 - getty #908 - sh #931 - initctl #944 - sshd #981 - kerneloops #1000 - cron #1006 - acpid #1018 - cups-browsed #1023 - whoopsie #1054 - VBoxService #1210 - getty #1276 - lightdm #1295 - Xorg #1319 - lightdm #1340 - mate-session #1355 - ssh-agent #1446 - mate-settings-d #1541 - marco #1545 - zenity #8779 - mate-panel #1549 - mate-terminal #1864 - gnome-pty-helpe #1873 - zsh #1874 - pstree #15186 - emacs #13667 - pstree #15186 - zsh #7803 - java #8648 - caja #1558 - polkit-mate-aut #1587 - deja-dup-monito #1589 - indicator-power #1593 - indicator-bluet #1594 - update-notifier #1600 - zeitgeist-datah #1607 - nm-applet #1613 - applet.py #1623 - accounts-daemon #1305 - VBoxClient #1423 - VBoxClient #1431 - VBoxClient #1436 - VBoxClient #1441 - dbus-launch #1450 - dbus-daemon #1461 - ibus-daemon #1476 - ibus-dconf #1493 - ibus-ui-gtk3 #1494 - ibus-engine-sim #1570 - gvfsd #1488 - ibus-x11 #1498 - gvfsd-fuse #1503 - dconf-service #1509 - gnome-keyring-d #1522 - at-spi-bus-laun #1528 - dbus-daemon #1532 - at-spi2-registr #1535 - pulseaudio #1561 - rtkit-daemon #1563 - gvfs-udisks2-vo #1572 - udisksd #1581 - upowerd #1599 - gvfs-mtp-volume #1630 - zeitgeist-daemo #1634 - gvfs-gphoto2-vo #1639 - gvfs-afc-volume #1671 - zeitgeist-fts #1708 - cat #1789 - wnck-applet #1767 - notification-ar #1769 - clock-applet #1771 - gvfsd-trash #1792 - gconfd-2 #1798 - cupsd #1858 - gvfsd-burn #8225 - geoclue-master #8247 - ubuntu-geoip-pr #8251 - gvfsd-http #8281 - master #11380 - qmgr #11383 - pickup #13717 - notify-osd #11677 - gnome-screensav #11715 - gvfsd-metadata #13196 - oneconf-service #15144 - kthreadd #2 - ksoftirqd/0 #3 - rcu_sched #7 - rcuos/0 #8 - rcuos/1 #9 - rcu_bh #10 - rcuob/0 #11 - rcuob/1 #12 - migration/0 #13 - watchdog/0 #14 - watchdog/1 #15 - migration/1 #16 - ksoftirqd/1 #17 - khelper #20 - kdevtmpfs #21 - netns #22 - writeback #23 - kintegrityd #24 - bioset #25 - kblockd #27 - ata_sff #28 - khubd #29 - md #30 - devfreq_wq #31 - khungtaskd #33 - kswapd0 #34 - ksmd #35 - khugepaged #36 - fsnotify_mark #37 - ecryptfs-kthrea #38 - crypto #39 - kthrotld #51 - scsi_eh_0 #54 - scsi_eh_1 #55 - deferwq #76 - charger_manager #77 - scsi_eh_2 #118 - kpsmoused #122 - kdmflush #138 - bioset #139 - kdmflush #140 - bioset #141 - jbd2/dm-0-8 #157 - ext4-rsv-conver #158 - ext4-rsv-conver #341 - iprt #422 - krfcommd #694 - kauditd #1345
2014-10-14 10:57:18 +02:00
fn get_process_record(status_path: &Path) -> Option<ProcessRecord> {
let mut pid : Option<i32> = None;
let mut ppid : Option<i32> = None;
let mut name : Option<String> = None;
let mut reader = std::io::BufReader::new(File::open(status_path).unwrap());
loop {
let mut linebuf = String::new();
match reader.read_line(&mut linebuf) {
Ok(_) => {
if linebuf.is_empty() {
break;
}
let parts : Vec<&str> = linebuf[..].splitn(2, ':').collect();
if parts.len() == 2 {
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() {
Some(ProcessRecord { name: name.unwrap(), pid: pid.unwrap(), ppid: ppid.unwrap() })
} else {
None
}
}
pstree: It works... it actually works! Lots of learning along the way and realizations that Rust's manual memory management actually prevents you from doing bad things that you might otherwise want to do. Fair enough. Lots of syntactic struggles and wishin the language was managed at times. - / #0 - init #1 - upstart-udev-br #295 - systemd-udevd #303 - upstart-file-br #391 - rsyslogd #443 - dbus-daemon #499 - upstart-socket- #507 - ModemManager #579 - bluetoothd #581 - systemd-logind #593 - avahi-daemon #686 - avahi-daemon #688 - NetworkManager #777 - dhclient #1046 - dnsmasq #1060 - getty #859 - getty #863 - polkitd #899 - getty #904 - getty #905 - getty #908 - sh #931 - initctl #944 - sshd #981 - kerneloops #1000 - cron #1006 - acpid #1018 - cups-browsed #1023 - whoopsie #1054 - VBoxService #1210 - getty #1276 - lightdm #1295 - Xorg #1319 - lightdm #1340 - mate-session #1355 - ssh-agent #1446 - mate-settings-d #1541 - marco #1545 - zenity #8779 - mate-panel #1549 - mate-terminal #1864 - gnome-pty-helpe #1873 - zsh #1874 - pstree #15186 - emacs #13667 - pstree #15186 - zsh #7803 - java #8648 - caja #1558 - polkit-mate-aut #1587 - deja-dup-monito #1589 - indicator-power #1593 - indicator-bluet #1594 - update-notifier #1600 - zeitgeist-datah #1607 - nm-applet #1613 - applet.py #1623 - accounts-daemon #1305 - VBoxClient #1423 - VBoxClient #1431 - VBoxClient #1436 - VBoxClient #1441 - dbus-launch #1450 - dbus-daemon #1461 - ibus-daemon #1476 - ibus-dconf #1493 - ibus-ui-gtk3 #1494 - ibus-engine-sim #1570 - gvfsd #1488 - ibus-x11 #1498 - gvfsd-fuse #1503 - dconf-service #1509 - gnome-keyring-d #1522 - at-spi-bus-laun #1528 - dbus-daemon #1532 - at-spi2-registr #1535 - pulseaudio #1561 - rtkit-daemon #1563 - gvfs-udisks2-vo #1572 - udisksd #1581 - upowerd #1599 - gvfs-mtp-volume #1630 - zeitgeist-daemo #1634 - gvfs-gphoto2-vo #1639 - gvfs-afc-volume #1671 - zeitgeist-fts #1708 - cat #1789 - wnck-applet #1767 - notification-ar #1769 - clock-applet #1771 - gvfsd-trash #1792 - gconfd-2 #1798 - cupsd #1858 - gvfsd-burn #8225 - geoclue-master #8247 - ubuntu-geoip-pr #8251 - gvfsd-http #8281 - master #11380 - qmgr #11383 - pickup #13717 - notify-osd #11677 - gnome-screensav #11715 - gvfsd-metadata #13196 - oneconf-service #15144 - kthreadd #2 - ksoftirqd/0 #3 - rcu_sched #7 - rcuos/0 #8 - rcuos/1 #9 - rcu_bh #10 - rcuob/0 #11 - rcuob/1 #12 - migration/0 #13 - watchdog/0 #14 - watchdog/1 #15 - migration/1 #16 - ksoftirqd/1 #17 - khelper #20 - kdevtmpfs #21 - netns #22 - writeback #23 - kintegrityd #24 - bioset #25 - kblockd #27 - ata_sff #28 - khubd #29 - md #30 - devfreq_wq #31 - khungtaskd #33 - kswapd0 #34 - ksmd #35 - khugepaged #36 - fsnotify_mark #37 - ecryptfs-kthrea #38 - crypto #39 - kthrotld #51 - scsi_eh_0 #54 - scsi_eh_1 #55 - deferwq #76 - charger_manager #77 - scsi_eh_2 #118 - kpsmoused #122 - kdmflush #138 - bioset #139 - kdmflush #140 - bioset #141 - jbd2/dm-0-8 #157 - ext4-rsv-conver #158 - ext4-rsv-conver #341 - iprt #422 - krfcommd #694 - kauditd #1345
2014-10-14 10:57:18 +02:00
// build a simple struct (ProcessRecord) for each process
fn get_process_records() -> Vec<ProcessRecord> {
let proc_directory = Path::new("/proc");
pstree: It works... it actually works! Lots of learning along the way and realizations that Rust's manual memory management actually prevents you from doing bad things that you might otherwise want to do. Fair enough. Lots of syntactic struggles and wishin the language was managed at times. - / #0 - init #1 - upstart-udev-br #295 - systemd-udevd #303 - upstart-file-br #391 - rsyslogd #443 - dbus-daemon #499 - upstart-socket- #507 - ModemManager #579 - bluetoothd #581 - systemd-logind #593 - avahi-daemon #686 - avahi-daemon #688 - NetworkManager #777 - dhclient #1046 - dnsmasq #1060 - getty #859 - getty #863 - polkitd #899 - getty #904 - getty #905 - getty #908 - sh #931 - initctl #944 - sshd #981 - kerneloops #1000 - cron #1006 - acpid #1018 - cups-browsed #1023 - whoopsie #1054 - VBoxService #1210 - getty #1276 - lightdm #1295 - Xorg #1319 - lightdm #1340 - mate-session #1355 - ssh-agent #1446 - mate-settings-d #1541 - marco #1545 - zenity #8779 - mate-panel #1549 - mate-terminal #1864 - gnome-pty-helpe #1873 - zsh #1874 - pstree #15186 - emacs #13667 - pstree #15186 - zsh #7803 - java #8648 - caja #1558 - polkit-mate-aut #1587 - deja-dup-monito #1589 - indicator-power #1593 - indicator-bluet #1594 - update-notifier #1600 - zeitgeist-datah #1607 - nm-applet #1613 - applet.py #1623 - accounts-daemon #1305 - VBoxClient #1423 - VBoxClient #1431 - VBoxClient #1436 - VBoxClient #1441 - dbus-launch #1450 - dbus-daemon #1461 - ibus-daemon #1476 - ibus-dconf #1493 - ibus-ui-gtk3 #1494 - ibus-engine-sim #1570 - gvfsd #1488 - ibus-x11 #1498 - gvfsd-fuse #1503 - dconf-service #1509 - gnome-keyring-d #1522 - at-spi-bus-laun #1528 - dbus-daemon #1532 - at-spi2-registr #1535 - pulseaudio #1561 - rtkit-daemon #1563 - gvfs-udisks2-vo #1572 - udisksd #1581 - upowerd #1599 - gvfs-mtp-volume #1630 - zeitgeist-daemo #1634 - gvfs-gphoto2-vo #1639 - gvfs-afc-volume #1671 - zeitgeist-fts #1708 - cat #1789 - wnck-applet #1767 - notification-ar #1769 - clock-applet #1771 - gvfsd-trash #1792 - gconfd-2 #1798 - cupsd #1858 - gvfsd-burn #8225 - geoclue-master #8247 - ubuntu-geoip-pr #8251 - gvfsd-http #8281 - master #11380 - qmgr #11383 - pickup #13717 - notify-osd #11677 - gnome-screensav #11715 - gvfsd-metadata #13196 - oneconf-service #15144 - kthreadd #2 - ksoftirqd/0 #3 - rcu_sched #7 - rcuos/0 #8 - rcuos/1 #9 - rcu_bh #10 - rcuob/0 #11 - rcuob/1 #12 - migration/0 #13 - watchdog/0 #14 - watchdog/1 #15 - migration/1 #16 - ksoftirqd/1 #17 - khelper #20 - kdevtmpfs #21 - netns #22 - writeback #23 - kintegrityd #24 - bioset #25 - kblockd #27 - ata_sff #28 - khubd #29 - md #30 - devfreq_wq #31 - khungtaskd #33 - kswapd0 #34 - ksmd #35 - khugepaged #36 - fsnotify_mark #37 - ecryptfs-kthrea #38 - crypto #39 - kthrotld #51 - scsi_eh_0 #54 - scsi_eh_1 #55 - deferwq #76 - charger_manager #77 - scsi_eh_2 #118 - kpsmoused #122 - kdmflush #138 - bioset #139 - kdmflush #140 - bioset #141 - jbd2/dm-0-8 #157 - ext4-rsv-conver #158 - ext4-rsv-conver #341 - iprt #422 - krfcommd #694 - kauditd #1345
2014-10-14 10:57:18 +02:00
// find potential process directories under /proc
let proc_directory_contents = fs::read_dir(&proc_directory).unwrap();
proc_directory_contents.filter_map(|entry| {
let entry_path = entry.unwrap().path();
if entry_path.is_dir() {
let status_path = entry_path.join("status");
if status_path.exists() {
return get_process_record(&status_path)
}
}
None
}).collect()
pstree: It works... it actually works! Lots of learning along the way and realizations that Rust's manual memory management actually prevents you from doing bad things that you might otherwise want to do. Fair enough. Lots of syntactic struggles and wishin the language was managed at times. - / #0 - init #1 - upstart-udev-br #295 - systemd-udevd #303 - upstart-file-br #391 - rsyslogd #443 - dbus-daemon #499 - upstart-socket- #507 - ModemManager #579 - bluetoothd #581 - systemd-logind #593 - avahi-daemon #686 - avahi-daemon #688 - NetworkManager #777 - dhclient #1046 - dnsmasq #1060 - getty #859 - getty #863 - polkitd #899 - getty #904 - getty #905 - getty #908 - sh #931 - initctl #944 - sshd #981 - kerneloops #1000 - cron #1006 - acpid #1018 - cups-browsed #1023 - whoopsie #1054 - VBoxService #1210 - getty #1276 - lightdm #1295 - Xorg #1319 - lightdm #1340 - mate-session #1355 - ssh-agent #1446 - mate-settings-d #1541 - marco #1545 - zenity #8779 - mate-panel #1549 - mate-terminal #1864 - gnome-pty-helpe #1873 - zsh #1874 - pstree #15186 - emacs #13667 - pstree #15186 - zsh #7803 - java #8648 - caja #1558 - polkit-mate-aut #1587 - deja-dup-monito #1589 - indicator-power #1593 - indicator-bluet #1594 - update-notifier #1600 - zeitgeist-datah #1607 - nm-applet #1613 - applet.py #1623 - accounts-daemon #1305 - VBoxClient #1423 - VBoxClient #1431 - VBoxClient #1436 - VBoxClient #1441 - dbus-launch #1450 - dbus-daemon #1461 - ibus-daemon #1476 - ibus-dconf #1493 - ibus-ui-gtk3 #1494 - ibus-engine-sim #1570 - gvfsd #1488 - ibus-x11 #1498 - gvfsd-fuse #1503 - dconf-service #1509 - gnome-keyring-d #1522 - at-spi-bus-laun #1528 - dbus-daemon #1532 - at-spi2-registr #1535 - pulseaudio #1561 - rtkit-daemon #1563 - gvfs-udisks2-vo #1572 - udisksd #1581 - upowerd #1599 - gvfs-mtp-volume #1630 - zeitgeist-daemo #1634 - gvfs-gphoto2-vo #1639 - gvfs-afc-volume #1671 - zeitgeist-fts #1708 - cat #1789 - wnck-applet #1767 - notification-ar #1769 - clock-applet #1771 - gvfsd-trash #1792 - gconfd-2 #1798 - cupsd #1858 - gvfsd-burn #8225 - geoclue-master #8247 - ubuntu-geoip-pr #8251 - gvfsd-http #8281 - master #11380 - qmgr #11383 - pickup #13717 - notify-osd #11677 - gnome-screensav #11715 - gvfsd-metadata #13196 - oneconf-service #15144 - kthreadd #2 - ksoftirqd/0 #3 - rcu_sched #7 - rcuos/0 #8 - rcuos/1 #9 - rcu_bh #10 - rcuob/0 #11 - rcuob/1 #12 - migration/0 #13 - watchdog/0 #14 - watchdog/1 #15 - migration/1 #16 - ksoftirqd/1 #17 - khelper #20 - kdevtmpfs #21 - netns #22 - writeback #23 - kintegrityd #24 - bioset #25 - kblockd #27 - ata_sff #28 - khubd #29 - md #30 - devfreq_wq #31 - khungtaskd #33 - kswapd0 #34 - ksmd #35 - khugepaged #36 - fsnotify_mark #37 - ecryptfs-kthrea #38 - crypto #39 - kthrotld #51 - scsi_eh_0 #54 - scsi_eh_1 #55 - deferwq #76 - charger_manager #77 - scsi_eh_2 #118 - kpsmoused #122 - kdmflush #138 - bioset #139 - kdmflush #140 - bioset #141 - jbd2/dm-0-8 #157 - ext4-rsv-conver #158 - ext4-rsv-conver #341 - iprt #422 - krfcommd #694 - kauditd #1345
2014-10-14 10:57:18 +02:00
}
fn populate_node_helper(node: &mut ProcessTreeNode, pid_map: &HashMap<i32, &ProcessRecord>, ppid_map: &HashMap<i32, Vec<i32>>) {
pstree: It works... it actually works! Lots of learning along the way and realizations that Rust's manual memory management actually prevents you from doing bad things that you might otherwise want to do. Fair enough. Lots of syntactic struggles and wishin the language was managed at times. - / #0 - init #1 - upstart-udev-br #295 - systemd-udevd #303 - upstart-file-br #391 - rsyslogd #443 - dbus-daemon #499 - upstart-socket- #507 - ModemManager #579 - bluetoothd #581 - systemd-logind #593 - avahi-daemon #686 - avahi-daemon #688 - NetworkManager #777 - dhclient #1046 - dnsmasq #1060 - getty #859 - getty #863 - polkitd #899 - getty #904 - getty #905 - getty #908 - sh #931 - initctl #944 - sshd #981 - kerneloops #1000 - cron #1006 - acpid #1018 - cups-browsed #1023 - whoopsie #1054 - VBoxService #1210 - getty #1276 - lightdm #1295 - Xorg #1319 - lightdm #1340 - mate-session #1355 - ssh-agent #1446 - mate-settings-d #1541 - marco #1545 - zenity #8779 - mate-panel #1549 - mate-terminal #1864 - gnome-pty-helpe #1873 - zsh #1874 - pstree #15186 - emacs #13667 - pstree #15186 - zsh #7803 - java #8648 - caja #1558 - polkit-mate-aut #1587 - deja-dup-monito #1589 - indicator-power #1593 - indicator-bluet #1594 - update-notifier #1600 - zeitgeist-datah #1607 - nm-applet #1613 - applet.py #1623 - accounts-daemon #1305 - VBoxClient #1423 - VBoxClient #1431 - VBoxClient #1436 - VBoxClient #1441 - dbus-launch #1450 - dbus-daemon #1461 - ibus-daemon #1476 - ibus-dconf #1493 - ibus-ui-gtk3 #1494 - ibus-engine-sim #1570 - gvfsd #1488 - ibus-x11 #1498 - gvfsd-fuse #1503 - dconf-service #1509 - gnome-keyring-d #1522 - at-spi-bus-laun #1528 - dbus-daemon #1532 - at-spi2-registr #1535 - pulseaudio #1561 - rtkit-daemon #1563 - gvfs-udisks2-vo #1572 - udisksd #1581 - upowerd #1599 - gvfs-mtp-volume #1630 - zeitgeist-daemo #1634 - gvfs-gphoto2-vo #1639 - gvfs-afc-volume #1671 - zeitgeist-fts #1708 - cat #1789 - wnck-applet #1767 - notification-ar #1769 - clock-applet #1771 - gvfsd-trash #1792 - gconfd-2 #1798 - cupsd #1858 - gvfsd-burn #8225 - geoclue-master #8247 - ubuntu-geoip-pr #8251 - gvfsd-http #8281 - master #11380 - qmgr #11383 - pickup #13717 - notify-osd #11677 - gnome-screensav #11715 - gvfsd-metadata #13196 - oneconf-service #15144 - kthreadd #2 - ksoftirqd/0 #3 - rcu_sched #7 - rcuos/0 #8 - rcuos/1 #9 - rcu_bh #10 - rcuob/0 #11 - rcuob/1 #12 - migration/0 #13 - watchdog/0 #14 - watchdog/1 #15 - migration/1 #16 - ksoftirqd/1 #17 - khelper #20 - kdevtmpfs #21 - netns #22 - writeback #23 - kintegrityd #24 - bioset #25 - kblockd #27 - ata_sff #28 - khubd #29 - md #30 - devfreq_wq #31 - khungtaskd #33 - kswapd0 #34 - ksmd #35 - khugepaged #36 - fsnotify_mark #37 - ecryptfs-kthrea #38 - crypto #39 - kthrotld #51 - scsi_eh_0 #54 - scsi_eh_1 #55 - deferwq #76 - charger_manager #77 - scsi_eh_2 #118 - kpsmoused #122 - kdmflush #138 - bioset #139 - kdmflush #140 - bioset #141 - jbd2/dm-0-8 #157 - ext4-rsv-conver #158 - ext4-rsv-conver #341 - iprt #422 - krfcommd #694 - kauditd #1345
2014-10-14 10:57:18 +02:00
let pid = node.record.pid; // avoid binding node as immutable in closure
let child_nodes = &mut node.children;
match ppid_map.get(&pid) {
Some(children) => {
child_nodes.extend(children.iter().map(|child_pid| {
let record = pid_map[*child_pid];
let mut child = ProcessTreeNode::new(record);
populate_node_helper(&mut child, pid_map, ppid_map);
child
}));
},
None => {},
}
}
fn populate_node(node : &mut ProcessTreeNode, records: &Vec<ProcessRecord>) {
// O(n): build a mapping of pids to vectors of children. That is, each
// key is a pid and its value is a vector of the whose parent pid is the key
let mut ppid_map : HashMap<i32, Vec<i32>> = HashMap::new();
let mut pid_map : HashMap<i32, &ProcessRecord> = HashMap::new();
for record in records.iter() {
// entry returns either a vacant or occupied entry. If vacant,
// we insert a new vector with this records pid. If occupied,
// we push this record's pid onto the vec
pid_map.insert(record.pid, record);
match ppid_map.entry(record.ppid) {
Vacant(entry) => { entry.insert(vec![record.pid]); },
Occupied(mut entry) => { entry.get_mut().push(record.pid); },
};
}
// With the data structures built, it is off to the races
populate_node_helper(node, &pid_map, &ppid_map);
pstree: It works... it actually works! Lots of learning along the way and realizations that Rust's manual memory management actually prevents you from doing bad things that you might otherwise want to do. Fair enough. Lots of syntactic struggles and wishin the language was managed at times. - / #0 - init #1 - upstart-udev-br #295 - systemd-udevd #303 - upstart-file-br #391 - rsyslogd #443 - dbus-daemon #499 - upstart-socket- #507 - ModemManager #579 - bluetoothd #581 - systemd-logind #593 - avahi-daemon #686 - avahi-daemon #688 - NetworkManager #777 - dhclient #1046 - dnsmasq #1060 - getty #859 - getty #863 - polkitd #899 - getty #904 - getty #905 - getty #908 - sh #931 - initctl #944 - sshd #981 - kerneloops #1000 - cron #1006 - acpid #1018 - cups-browsed #1023 - whoopsie #1054 - VBoxService #1210 - getty #1276 - lightdm #1295 - Xorg #1319 - lightdm #1340 - mate-session #1355 - ssh-agent #1446 - mate-settings-d #1541 - marco #1545 - zenity #8779 - mate-panel #1549 - mate-terminal #1864 - gnome-pty-helpe #1873 - zsh #1874 - pstree #15186 - emacs #13667 - pstree #15186 - zsh #7803 - java #8648 - caja #1558 - polkit-mate-aut #1587 - deja-dup-monito #1589 - indicator-power #1593 - indicator-bluet #1594 - update-notifier #1600 - zeitgeist-datah #1607 - nm-applet #1613 - applet.py #1623 - accounts-daemon #1305 - VBoxClient #1423 - VBoxClient #1431 - VBoxClient #1436 - VBoxClient #1441 - dbus-launch #1450 - dbus-daemon #1461 - ibus-daemon #1476 - ibus-dconf #1493 - ibus-ui-gtk3 #1494 - ibus-engine-sim #1570 - gvfsd #1488 - ibus-x11 #1498 - gvfsd-fuse #1503 - dconf-service #1509 - gnome-keyring-d #1522 - at-spi-bus-laun #1528 - dbus-daemon #1532 - at-spi2-registr #1535 - pulseaudio #1561 - rtkit-daemon #1563 - gvfs-udisks2-vo #1572 - udisksd #1581 - upowerd #1599 - gvfs-mtp-volume #1630 - zeitgeist-daemo #1634 - gvfs-gphoto2-vo #1639 - gvfs-afc-volume #1671 - zeitgeist-fts #1708 - cat #1789 - wnck-applet #1767 - notification-ar #1769 - clock-applet #1771 - gvfsd-trash #1792 - gconfd-2 #1798 - cupsd #1858 - gvfsd-burn #8225 - geoclue-master #8247 - ubuntu-geoip-pr #8251 - gvfsd-http #8281 - master #11380 - qmgr #11383 - pickup #13717 - notify-osd #11677 - gnome-screensav #11715 - gvfsd-metadata #13196 - oneconf-service #15144 - kthreadd #2 - ksoftirqd/0 #3 - rcu_sched #7 - rcuos/0 #8 - rcuos/1 #9 - rcu_bh #10 - rcuob/0 #11 - rcuob/1 #12 - migration/0 #13 - watchdog/0 #14 - watchdog/1 #15 - migration/1 #16 - ksoftirqd/1 #17 - khelper #20 - kdevtmpfs #21 - netns #22 - writeback #23 - kintegrityd #24 - bioset #25 - kblockd #27 - ata_sff #28 - khubd #29 - md #30 - devfreq_wq #31 - khungtaskd #33 - kswapd0 #34 - ksmd #35 - khugepaged #36 - fsnotify_mark #37 - ecryptfs-kthrea #38 - crypto #39 - kthrotld #51 - scsi_eh_0 #54 - scsi_eh_1 #55 - deferwq #76 - charger_manager #77 - scsi_eh_2 #118 - kpsmoused #122 - kdmflush #138 - bioset #139 - kdmflush #140 - bioset #141 - jbd2/dm-0-8 #157 - ext4-rsv-conver #158 - ext4-rsv-conver #341 - iprt #422 - krfcommd #694 - kauditd #1345
2014-10-14 10:57:18 +02:00
}
fn build_process_tree() -> ProcessTree {
let records = get_process_records();
let mut tree = ProcessTree {
root : ProcessTreeNode::new(
&ProcessRecord {
name: "/".to_string(),
pid: 0,
ppid: -1
})
pstree: It works... it actually works! Lots of learning along the way and realizations that Rust's manual memory management actually prevents you from doing bad things that you might otherwise want to do. Fair enough. Lots of syntactic struggles and wishin the language was managed at times. - / #0 - init #1 - upstart-udev-br #295 - systemd-udevd #303 - upstart-file-br #391 - rsyslogd #443 - dbus-daemon #499 - upstart-socket- #507 - ModemManager #579 - bluetoothd #581 - systemd-logind #593 - avahi-daemon #686 - avahi-daemon #688 - NetworkManager #777 - dhclient #1046 - dnsmasq #1060 - getty #859 - getty #863 - polkitd #899 - getty #904 - getty #905 - getty #908 - sh #931 - initctl #944 - sshd #981 - kerneloops #1000 - cron #1006 - acpid #1018 - cups-browsed #1023 - whoopsie #1054 - VBoxService #1210 - getty #1276 - lightdm #1295 - Xorg #1319 - lightdm #1340 - mate-session #1355 - ssh-agent #1446 - mate-settings-d #1541 - marco #1545 - zenity #8779 - mate-panel #1549 - mate-terminal #1864 - gnome-pty-helpe #1873 - zsh #1874 - pstree #15186 - emacs #13667 - pstree #15186 - zsh #7803 - java #8648 - caja #1558 - polkit-mate-aut #1587 - deja-dup-monito #1589 - indicator-power #1593 - indicator-bluet #1594 - update-notifier #1600 - zeitgeist-datah #1607 - nm-applet #1613 - applet.py #1623 - accounts-daemon #1305 - VBoxClient #1423 - VBoxClient #1431 - VBoxClient #1436 - VBoxClient #1441 - dbus-launch #1450 - dbus-daemon #1461 - ibus-daemon #1476 - ibus-dconf #1493 - ibus-ui-gtk3 #1494 - ibus-engine-sim #1570 - gvfsd #1488 - ibus-x11 #1498 - gvfsd-fuse #1503 - dconf-service #1509 - gnome-keyring-d #1522 - at-spi-bus-laun #1528 - dbus-daemon #1532 - at-spi2-registr #1535 - pulseaudio #1561 - rtkit-daemon #1563 - gvfs-udisks2-vo #1572 - udisksd #1581 - upowerd #1599 - gvfs-mtp-volume #1630 - zeitgeist-daemo #1634 - gvfs-gphoto2-vo #1639 - gvfs-afc-volume #1671 - zeitgeist-fts #1708 - cat #1789 - wnck-applet #1767 - notification-ar #1769 - clock-applet #1771 - gvfsd-trash #1792 - gconfd-2 #1798 - cupsd #1858 - gvfsd-burn #8225 - geoclue-master #8247 - ubuntu-geoip-pr #8251 - gvfsd-http #8281 - master #11380 - qmgr #11383 - pickup #13717 - notify-osd #11677 - gnome-screensav #11715 - gvfsd-metadata #13196 - oneconf-service #15144 - kthreadd #2 - ksoftirqd/0 #3 - rcu_sched #7 - rcuos/0 #8 - rcuos/1 #9 - rcu_bh #10 - rcuob/0 #11 - rcuob/1 #12 - migration/0 #13 - watchdog/0 #14 - watchdog/1 #15 - migration/1 #16 - ksoftirqd/1 #17 - khelper #20 - kdevtmpfs #21 - netns #22 - writeback #23 - kintegrityd #24 - bioset #25 - kblockd #27 - ata_sff #28 - khubd #29 - md #30 - devfreq_wq #31 - khungtaskd #33 - kswapd0 #34 - ksmd #35 - khugepaged #36 - fsnotify_mark #37 - ecryptfs-kthrea #38 - crypto #39 - kthrotld #51 - scsi_eh_0 #54 - scsi_eh_1 #55 - deferwq #76 - charger_manager #77 - scsi_eh_2 #118 - kpsmoused #122 - kdmflush #138 - bioset #139 - kdmflush #140 - bioset #141 - jbd2/dm-0-8 #157 - ext4-rsv-conver #158 - ext4-rsv-conver #341 - iprt #422 - krfcommd #694 - kauditd #1345
2014-10-14 10:57:18 +02:00
};
// recursively populate all nodes in the tree starting from root (pid 0)
{
let root = &mut tree.root;
populate_node(root, &records);
}
tree
}
fn print_node(node : &ProcessTreeNode, indent_level : i32) {
pstree: It works... it actually works! Lots of learning along the way and realizations that Rust's manual memory management actually prevents you from doing bad things that you might otherwise want to do. Fair enough. Lots of syntactic struggles and wishin the language was managed at times. - / #0 - init #1 - upstart-udev-br #295 - systemd-udevd #303 - upstart-file-br #391 - rsyslogd #443 - dbus-daemon #499 - upstart-socket- #507 - ModemManager #579 - bluetoothd #581 - systemd-logind #593 - avahi-daemon #686 - avahi-daemon #688 - NetworkManager #777 - dhclient #1046 - dnsmasq #1060 - getty #859 - getty #863 - polkitd #899 - getty #904 - getty #905 - getty #908 - sh #931 - initctl #944 - sshd #981 - kerneloops #1000 - cron #1006 - acpid #1018 - cups-browsed #1023 - whoopsie #1054 - VBoxService #1210 - getty #1276 - lightdm #1295 - Xorg #1319 - lightdm #1340 - mate-session #1355 - ssh-agent #1446 - mate-settings-d #1541 - marco #1545 - zenity #8779 - mate-panel #1549 - mate-terminal #1864 - gnome-pty-helpe #1873 - zsh #1874 - pstree #15186 - emacs #13667 - pstree #15186 - zsh #7803 - java #8648 - caja #1558 - polkit-mate-aut #1587 - deja-dup-monito #1589 - indicator-power #1593 - indicator-bluet #1594 - update-notifier #1600 - zeitgeist-datah #1607 - nm-applet #1613 - applet.py #1623 - accounts-daemon #1305 - VBoxClient #1423 - VBoxClient #1431 - VBoxClient #1436 - VBoxClient #1441 - dbus-launch #1450 - dbus-daemon #1461 - ibus-daemon #1476 - ibus-dconf #1493 - ibus-ui-gtk3 #1494 - ibus-engine-sim #1570 - gvfsd #1488 - ibus-x11 #1498 - gvfsd-fuse #1503 - dconf-service #1509 - gnome-keyring-d #1522 - at-spi-bus-laun #1528 - dbus-daemon #1532 - at-spi2-registr #1535 - pulseaudio #1561 - rtkit-daemon #1563 - gvfs-udisks2-vo #1572 - udisksd #1581 - upowerd #1599 - gvfs-mtp-volume #1630 - zeitgeist-daemo #1634 - gvfs-gphoto2-vo #1639 - gvfs-afc-volume #1671 - zeitgeist-fts #1708 - cat #1789 - wnck-applet #1767 - notification-ar #1769 - clock-applet #1771 - gvfsd-trash #1792 - gconfd-2 #1798 - cupsd #1858 - gvfsd-burn #8225 - geoclue-master #8247 - ubuntu-geoip-pr #8251 - gvfsd-http #8281 - master #11380 - qmgr #11383 - pickup #13717 - notify-osd #11677 - gnome-screensav #11715 - gvfsd-metadata #13196 - oneconf-service #15144 - kthreadd #2 - ksoftirqd/0 #3 - rcu_sched #7 - rcuos/0 #8 - rcuos/1 #9 - rcu_bh #10 - rcuob/0 #11 - rcuob/1 #12 - migration/0 #13 - watchdog/0 #14 - watchdog/1 #15 - migration/1 #16 - ksoftirqd/1 #17 - khelper #20 - kdevtmpfs #21 - netns #22 - writeback #23 - kintegrityd #24 - bioset #25 - kblockd #27 - ata_sff #28 - khubd #29 - md #30 - devfreq_wq #31 - khungtaskd #33 - kswapd0 #34 - ksmd #35 - khugepaged #36 - fsnotify_mark #37 - ecryptfs-kthrea #38 - crypto #39 - kthrotld #51 - scsi_eh_0 #54 - scsi_eh_1 #55 - deferwq #76 - charger_manager #77 - scsi_eh_2 #118 - kpsmoused #122 - kdmflush #138 - bioset #139 - kdmflush #140 - bioset #141 - jbd2/dm-0-8 #157 - ext4-rsv-conver #158 - ext4-rsv-conver #341 - iprt #422 - krfcommd #694 - kauditd #1345
2014-10-14 10:57:18 +02:00
// print indentation
for _ in (0..indent_level) {
print!(" ");
pstree: It works... it actually works! Lots of learning along the way and realizations that Rust's manual memory management actually prevents you from doing bad things that you might otherwise want to do. Fair enough. Lots of syntactic struggles and wishin the language was managed at times. - / #0 - init #1 - upstart-udev-br #295 - systemd-udevd #303 - upstart-file-br #391 - rsyslogd #443 - dbus-daemon #499 - upstart-socket- #507 - ModemManager #579 - bluetoothd #581 - systemd-logind #593 - avahi-daemon #686 - avahi-daemon #688 - NetworkManager #777 - dhclient #1046 - dnsmasq #1060 - getty #859 - getty #863 - polkitd #899 - getty #904 - getty #905 - getty #908 - sh #931 - initctl #944 - sshd #981 - kerneloops #1000 - cron #1006 - acpid #1018 - cups-browsed #1023 - whoopsie #1054 - VBoxService #1210 - getty #1276 - lightdm #1295 - Xorg #1319 - lightdm #1340 - mate-session #1355 - ssh-agent #1446 - mate-settings-d #1541 - marco #1545 - zenity #8779 - mate-panel #1549 - mate-terminal #1864 - gnome-pty-helpe #1873 - zsh #1874 - pstree #15186 - emacs #13667 - pstree #15186 - zsh #7803 - java #8648 - caja #1558 - polkit-mate-aut #1587 - deja-dup-monito #1589 - indicator-power #1593 - indicator-bluet #1594 - update-notifier #1600 - zeitgeist-datah #1607 - nm-applet #1613 - applet.py #1623 - accounts-daemon #1305 - VBoxClient #1423 - VBoxClient #1431 - VBoxClient #1436 - VBoxClient #1441 - dbus-launch #1450 - dbus-daemon #1461 - ibus-daemon #1476 - ibus-dconf #1493 - ibus-ui-gtk3 #1494 - ibus-engine-sim #1570 - gvfsd #1488 - ibus-x11 #1498 - gvfsd-fuse #1503 - dconf-service #1509 - gnome-keyring-d #1522 - at-spi-bus-laun #1528 - dbus-daemon #1532 - at-spi2-registr #1535 - pulseaudio #1561 - rtkit-daemon #1563 - gvfs-udisks2-vo #1572 - udisksd #1581 - upowerd #1599 - gvfs-mtp-volume #1630 - zeitgeist-daemo #1634 - gvfs-gphoto2-vo #1639 - gvfs-afc-volume #1671 - zeitgeist-fts #1708 - cat #1789 - wnck-applet #1767 - notification-ar #1769 - clock-applet #1771 - gvfsd-trash #1792 - gconfd-2 #1798 - cupsd #1858 - gvfsd-burn #8225 - geoclue-master #8247 - ubuntu-geoip-pr #8251 - gvfsd-http #8281 - master #11380 - qmgr #11383 - pickup #13717 - notify-osd #11677 - gnome-screensav #11715 - gvfsd-metadata #13196 - oneconf-service #15144 - kthreadd #2 - ksoftirqd/0 #3 - rcu_sched #7 - rcuos/0 #8 - rcuos/1 #9 - rcu_bh #10 - rcuob/0 #11 - rcuob/1 #12 - migration/0 #13 - watchdog/0 #14 - watchdog/1 #15 - migration/1 #16 - ksoftirqd/1 #17 - khelper #20 - kdevtmpfs #21 - netns #22 - writeback #23 - kintegrityd #24 - bioset #25 - kblockd #27 - ata_sff #28 - khubd #29 - md #30 - devfreq_wq #31 - khungtaskd #33 - kswapd0 #34 - ksmd #35 - khugepaged #36 - fsnotify_mark #37 - ecryptfs-kthrea #38 - crypto #39 - kthrotld #51 - scsi_eh_0 #54 - scsi_eh_1 #55 - deferwq #76 - charger_manager #77 - scsi_eh_2 #118 - kpsmoused #122 - kdmflush #138 - bioset #139 - kdmflush #140 - bioset #141 - jbd2/dm-0-8 #157 - ext4-rsv-conver #158 - ext4-rsv-conver #341 - iprt #422 - krfcommd #694 - kauditd #1345
2014-10-14 10:57:18 +02:00
}
println!("- {} #{}", node.record.name, node.record.pid);
for child in node.children.iter() {
print_node(child, indent_level + 1); // recurse
}
}
fn main() {
pstree: It works... it actually works! Lots of learning along the way and realizations that Rust's manual memory management actually prevents you from doing bad things that you might otherwise want to do. Fair enough. Lots of syntactic struggles and wishin the language was managed at times. - / #0 - init #1 - upstart-udev-br #295 - systemd-udevd #303 - upstart-file-br #391 - rsyslogd #443 - dbus-daemon #499 - upstart-socket- #507 - ModemManager #579 - bluetoothd #581 - systemd-logind #593 - avahi-daemon #686 - avahi-daemon #688 - NetworkManager #777 - dhclient #1046 - dnsmasq #1060 - getty #859 - getty #863 - polkitd #899 - getty #904 - getty #905 - getty #908 - sh #931 - initctl #944 - sshd #981 - kerneloops #1000 - cron #1006 - acpid #1018 - cups-browsed #1023 - whoopsie #1054 - VBoxService #1210 - getty #1276 - lightdm #1295 - Xorg #1319 - lightdm #1340 - mate-session #1355 - ssh-agent #1446 - mate-settings-d #1541 - marco #1545 - zenity #8779 - mate-panel #1549 - mate-terminal #1864 - gnome-pty-helpe #1873 - zsh #1874 - pstree #15186 - emacs #13667 - pstree #15186 - zsh #7803 - java #8648 - caja #1558 - polkit-mate-aut #1587 - deja-dup-monito #1589 - indicator-power #1593 - indicator-bluet #1594 - update-notifier #1600 - zeitgeist-datah #1607 - nm-applet #1613 - applet.py #1623 - accounts-daemon #1305 - VBoxClient #1423 - VBoxClient #1431 - VBoxClient #1436 - VBoxClient #1441 - dbus-launch #1450 - dbus-daemon #1461 - ibus-daemon #1476 - ibus-dconf #1493 - ibus-ui-gtk3 #1494 - ibus-engine-sim #1570 - gvfsd #1488 - ibus-x11 #1498 - gvfsd-fuse #1503 - dconf-service #1509 - gnome-keyring-d #1522 - at-spi-bus-laun #1528 - dbus-daemon #1532 - at-spi2-registr #1535 - pulseaudio #1561 - rtkit-daemon #1563 - gvfs-udisks2-vo #1572 - udisksd #1581 - upowerd #1599 - gvfs-mtp-volume #1630 - zeitgeist-daemo #1634 - gvfs-gphoto2-vo #1639 - gvfs-afc-volume #1671 - zeitgeist-fts #1708 - cat #1789 - wnck-applet #1767 - notification-ar #1769 - clock-applet #1771 - gvfsd-trash #1792 - gconfd-2 #1798 - cupsd #1858 - gvfsd-burn #8225 - geoclue-master #8247 - ubuntu-geoip-pr #8251 - gvfsd-http #8281 - master #11380 - qmgr #11383 - pickup #13717 - notify-osd #11677 - gnome-screensav #11715 - gvfsd-metadata #13196 - oneconf-service #15144 - kthreadd #2 - ksoftirqd/0 #3 - rcu_sched #7 - rcuos/0 #8 - rcuos/1 #9 - rcu_bh #10 - rcuob/0 #11 - rcuob/1 #12 - migration/0 #13 - watchdog/0 #14 - watchdog/1 #15 - migration/1 #16 - ksoftirqd/1 #17 - khelper #20 - kdevtmpfs #21 - netns #22 - writeback #23 - kintegrityd #24 - bioset #25 - kblockd #27 - ata_sff #28 - khubd #29 - md #30 - devfreq_wq #31 - khungtaskd #33 - kswapd0 #34 - ksmd #35 - khugepaged #36 - fsnotify_mark #37 - ecryptfs-kthrea #38 - crypto #39 - kthrotld #51 - scsi_eh_0 #54 - scsi_eh_1 #55 - deferwq #76 - charger_manager #77 - scsi_eh_2 #118 - kpsmoused #122 - kdmflush #138 - bioset #139 - kdmflush #140 - bioset #141 - jbd2/dm-0-8 #157 - ext4-rsv-conver #158 - ext4-rsv-conver #341 - iprt #422 - krfcommd #694 - kauditd #1345
2014-10-14 10:57:18 +02:00
let ptree = build_process_tree();
print_node(&(ptree.root), 0)
}