Kaynağa Gözat

Shell partially working.

themultiplexer 8 yıl önce
ebeveyn
işleme
fab546b3b4
3 değiştirilmiş dosya ile 81 ekleme ve 12 silme
  1. 1
    0
      hw7/task2/Cargo.toml
  2. 78
    12
      hw7/task2/src/lib.rs
  3. 2
    0
      hw7/task2/src/shellerror.rs

+ 1
- 0
hw7/task2/Cargo.toml Dosyayı Görüntüle

@@ -4,3 +4,4 @@ version = "0.1.0"
4 4
 authors = ["Joshua Rutschmann <joshua.rutschmann@gmx.de>"]
5 5
 
6 6
 [dependencies]
7
+nix = "0.9.0"

+ 78
- 12
hw7/task2/src/lib.rs Dosyayı Görüntüle

@@ -1,22 +1,31 @@
1
+extern crate nix;
2
+
1 3
 use std::io::{BufRead, Write};
2 4
 use std::str::FromStr;
3 5
 use std::env;
4
-use std::ffi::OsString;
6
+use std::str::Split;
7
+use std::os::unix::io::RawFd;
8
+use std::ffi::{OsString, CString};
9
+use nix::unistd::ForkResult::{Child, Parent};
10
+use nix::sys::wait::{wait, WaitStatus};
11
+use nix::unistd::dup2;
12
+use nix::unistd::close;
13
+use nix::unistd::{execvp, fork, pipe, read, write};
5 14
 
6 15
 mod shellerror;
7 16
 
17
+use shellerror::ShellError;
18
+
8 19
 #[derive(PartialEq, Debug)]
9 20
 pub enum Command {
10 21
     Empty,
11 22
     Exit,
23
+    Program(String),
12 24
     Cd(Option<OsString>),
13 25
 }
14 26
 
15
-#[derive(PartialEq, Debug)]
16
-pub struct CommandNotFoundError;
17
-
18 27
 impl FromStr for Command {
19
-    type Err = CommandNotFoundError;
28
+    type Err = ShellError;
20 29
     fn from_str(s: &str) -> Result<Self, Self::Err> {
21 30
 
22 31
         let mut parts = s.split_whitespace();
@@ -24,17 +33,14 @@ impl FromStr for Command {
24 33
         match parts.next() {
25 34
             Some("exit") => Ok(Command::Exit),
26 35
             Some("cd") => Ok(Command::parse_cd(parts.next())),
27
-            Some(cmd) => {
28
-                //For use in next homework, to execute programs.
29
-                let _ = cmd;
30
-                Err(CommandNotFoundError)
36
+            Some(_) => {
37
+                Ok(Command::Program(s.to_string()))
31 38
             }
32 39
             None => Ok(Command::Empty),
33 40
         }
34 41
     }
35 42
 }
36 43
 
37
-
38 44
 impl Command {
39 45
     /// If the passed String exists, set the path of the Cd in the enum (as OsString)
40 46
     /// Returns **Command**
@@ -127,10 +133,61 @@ impl<R: BufRead, W: Write> Shell<R, W> {
127 133
 
128 134
     /// Runs a command.
129 135
     /// Currently only `cd` and `exit` are working.
130
-    fn run(&mut self, command: Command) -> Result<(), CommandNotFoundError> {
136
+    fn run(&mut self, command: Command) -> Result<(), ShellError> {
131 137
 
132 138
         match command {
133
-            Command::Empty => {}
139
+            Command::Empty => {},
140
+            Command::Program(cmd) => {
141
+
142
+                let mut commands = cmd.split('|');
143
+                let commands_vec: Vec<&str> = commands.collect();
144
+
145
+                if let Ok((reader, writer)) = pipe() {
146
+                    /*
147
+                    let pid = fork();
148
+                    match pid {
149
+                        Ok(Parent { .. }) => {
150
+                                //wait();
151
+                        }
152
+                        Ok(Child) => {
153
+
154
+                        }
155
+
156
+                        Err(_) => println!("Fatal error: Fork failed"),
157
+                    }
158
+                    */
159
+
160
+                    let sub_pid = fork();
161
+                    match sub_pid {
162
+                        Ok(Parent { .. }) => {
163
+                            if let Some(out) = commands_vec.get(1) {
164
+                                wait();
165
+                                close(writer).unwrap();
166
+                                dup2(reader, 0).unwrap();
167
+                                self.execute(out)
168
+                            } else {
169
+                                wait();
170
+                            }
171
+                        }
172
+                        Ok(Child) => {
173
+
174
+                            if let Some(thing) = commands_vec.get(0) {
175
+                                if let Some(_) = commands_vec.get(1) {
176
+                                    close(reader).unwrap();
177
+                                    dup2(writer, 1).unwrap();
178
+                                }
179
+                                self.execute(thing);
180
+                            }
181
+                        }
182
+
183
+                        Err(_) => println!("Fatal error: Fork failed"),
184
+                    }
185
+
186
+
187
+
188
+                }
189
+
190
+            },
134 191
             Command::Exit => self.should_exit = true,
135 192
             Command::Cd(_) => {
136 193
                 command.exec_cd();
@@ -138,4 +195,13 @@ impl<R: BufRead, W: Write> Shell<R, W> {
138 195
         }
139 196
         Ok(())
140 197
     }
198
+
199
+    fn execute(&self, cmd: &str){
200
+        let mut parts:Vec<&str> = cmd.split_whitespace().collect();
201
+        let args:Vec<CString> = parts.iter().map(|f| CString::new(*f).unwrap()).collect();
202
+        let t = args.into_boxed_slice();
203
+
204
+        execvp(&t[0], &t);
205
+    }
141 206
 }
207
+

+ 2
- 0
hw7/task2/src/shellerror.rs Dosyayı Görüntüle

@@ -0,0 +1,2 @@
1
+#[derive(PartialEq, Debug)]
2
+pub struct ShellError;

Loading…
İptal
Kaydet