Procházet zdrojové kódy

Merge branch 'hw5' of github.com:themultiplexer/bsys-ws17-grp11 into hw5

Lorenz Bung před 8 roky
rodič
revize
2cd7f0821d
3 změnil soubory, kde provedl 131 přidání a 5 odebrání
  1. 32
    3
      hw5/task1/src/child/mod.rs
  2. 92
    0
      hw5/task1/src/child/pstree.rs
  3. 7
    2
      hw5/task1/src/main.rs

+ 32
- 3
hw5/task1/src/child/mod.rs Zobrazit soubor

@@ -1,7 +1,36 @@
1
+use nix::unistd::{fork, getpid};
2
+use nix::sys::wait::wait;
3
+use nix::unistd::ForkResult::{Child, Parent};
1 4
 
2
-
5
+mod pstree;
3 6
 
4 7
 pub fn run_childs(start_pid: i32, arg: &str) -> Result<(), String> {
5
-    let count = arg.parse::<u32>();
6
-    match count { }
8
+    let count = arg.parse::<u8>();
9
+    match count {
10
+        Ok(value) => {
11
+            for i in 0..value {
12
+                let pid = fork();
13
+                match pid {
14
+                    Ok(Child) => {
15
+                        println!("hello, I am child (pid:{})", getpid());
16
+                    }
17
+                    Ok(Parent { child }) => {
18
+                        println!("hello, I am parent of {} (pid:{})", child, getpid());
19
+                        match wait(){
20
+                            Ok(ws) => { println!("{:?}", ws); }
21
+                            Err(_) => {}
22
+                        }
23
+                    }
24
+                    // panic, fork should never fail unless there is a
25
+                    // serious problem with the OS
26
+                    Err(_) => panic!("fork failed"),
27
+                }
28
+            }
29
+            pstree::print(start_pid);
30
+            Ok(())
31
+        },
32
+        Err(_) => {
33
+            Err("Parse Failed".to_string())
34
+        },
35
+    }
7 36
 }

+ 92
- 0
hw5/task1/src/child/pstree.rs Zobrazit soubor

@@ -0,0 +1,92 @@
1
+use procinfo::pid;
2
+
3
+/// Datenstruktur für einen Prozess.
4
+pub struct Process {
5
+    name: String,
6
+    pid: i32,
7
+    ppid: i32,
8
+}
9
+
10
+impl Process {
11
+    /// Erstellt eine Prozess-Datenstruktur aus procinfo::Stat.
12
+    pub fn new(with_pid: i32) -> Self {
13
+        if let Ok(stat) = pid::stat(with_pid) {
14
+            Process {
15
+                name: stat.command,
16
+                pid: stat.pid,
17
+                ppid: stat.ppid,
18
+            }
19
+        } else {
20
+            panic!("Internal Error: Process not found")
21
+        }
22
+    }
23
+
24
+    /// Erstellt eine Prozess-Datenstruktur aus procinfo::Stat.
25
+    pub fn me() -> Self {
26
+        if let Ok(my_pid) = pid::stat_self() {
27
+            Process::new(my_pid.pid)
28
+        } else {
29
+            panic!("Internal Error: I don't have a PID but I am running.")
30
+        }
31
+    }
32
+
33
+    /// Prüft ob das Prozess-Struct ein Elternprozess besitzt.
34
+    pub fn has_parent(&self) -> bool {
35
+        self.ppid != 0
36
+    }
37
+
38
+    /// Gibt den Elternprozess zurück.
39
+    pub fn parent(&self) -> Self {
40
+        Process::new(self.ppid)
41
+    }
42
+
43
+    /// Prüft ob das Prozess-Struct einen (entfernten) Elternprozess mit dem übergebenen pid hat.
44
+    pub fn has_parent_with_pid(&self, pid: i32) -> bool {
45
+        if self.pid == pid {
46
+            return true;
47
+        }
48
+
49
+        if self.has_parent() {
50
+            return self.parent().has_parent_with_pid(pid);
51
+        }
52
+
53
+        false
54
+    }
55
+
56
+    /// Gibt über Rekursion über die Eltern eine Prozesskette aus.
57
+    pub fn print_recursive(&self, to_pid: i32, output: &mut String) {
58
+
59
+        if output.len() == 0 {
60
+            *output = format!("{}({}){}", self.name, self.pid, output);
61
+        } else {
62
+            *output = format!("{}({})---{}", self.name, self.pid, output);
63
+        }
64
+
65
+        if self.has_parent() && self.pid != to_pid {
66
+            self.parent().print_recursive(to_pid, output);
67
+        }
68
+    }
69
+}
70
+
71
+/// Geht von eigenem Prozess aus und gibt die Prozesskette bis zum übergebenem PID aus
72
+/// und fängt mögliche Fehler ab.
73
+pub fn print(pid: i32) -> bool {
74
+
75
+    if let Err(_) = pid::stat(pid) {
76
+        println!("Invalid PID");
77
+        return false;
78
+    }
79
+
80
+    let my_proc = Process::me();
81
+
82
+    if !my_proc.has_parent_with_pid(pid) {
83
+        println!("This Process has no parent {}", pid);
84
+        return false;
85
+    }
86
+
87
+    let mut output = String::new();
88
+    my_proc.print_recursive(pid, &mut output);
89
+    println!("{}", output);
90
+
91
+    true
92
+}

+ 7
- 2
hw5/task1/src/main.rs Zobrazit soubor

@@ -1,4 +1,5 @@
1 1
 extern crate procinfo;
2
+extern crate nix;
2 3
 
3 4
 use std::env::args;
4 5
 
@@ -14,14 +15,18 @@ fn main() {
14 15
 
15 16
         match procinfo::pid::stat_self(){
16 17
             Ok(stat) => {
17
-                child::run_childs(stat.pid, &arguments[2]);
18
+                let result = child::run_childs(stat.pid, &arguments[1]);
19
+                match result {
20
+                    Ok(_) => {},
21
+                    Err(_) => {},
22
+                }
18 23
             },
19 24
             Err(_) => {},
20 25
         }
21 26
 
22 27
 
23 28
     } else {
24
-        zombie::run_zombie();
29
+        //zombie::run_zombie();
25 30
     }
26 31
 
27 32
 }

Loading…
Zrušit
Uložit