diff options
Diffstat (limited to 'src/parser/command.rs')
-rw-r--r-- | src/parser/command.rs | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/src/parser/command.rs b/src/parser/command.rs index 496614f..52b4666 100644 --- a/src/parser/command.rs +++ b/src/parser/command.rs @@ -1,5 +1,6 @@ use std::io::{Error, ErrorKind}; use std::path::{Path, PathBuf}; +use std::process::{Command, ExitStatus}; #[derive(Debug)] pub enum Redirect { @@ -16,7 +17,7 @@ pub enum RunOn { } pub enum RunResult { - Command(std::process::ExitStatus), + Command(ExitStatus), Builtin, } @@ -40,34 +41,28 @@ impl CommandInfo { &self, home: &PathBuf, cwd: &mut PathBuf, - status: &Option<std::process::ExitStatus>, + status: &Option<ExitStatus>, ) -> Result<RunResult, Error> { match self.args[0].as_str() { "!" => { println!("{:?}", status); Ok(RunResult::Builtin) } - "cd" => match cd(&self.args[1..], home) { - Ok(p) => { - *cwd = p; - Ok(RunResult::Builtin) - } - Err(e) => Err(e), - }, + "cd" => cd(&self.args[1..], home, cwd), "exit" => { std::process::exit(0); } + "set" => set(&self.args[1..]), + "unset" => unset(&self.args[1..]), _ => { - let mut child = std::process::Command::new(&self.args[0]) - .args(&self.args[1..]) - .spawn()?; + let mut child = Command::new(&self.args[0]).args(&self.args[1..]).spawn()?; Ok(RunResult::Command(child.wait().unwrap())) } } } } -fn cd(args: &[String], home: &PathBuf) -> Result<PathBuf, Error> { +fn cd(args: &[String], home: &PathBuf, cwd: &mut PathBuf) -> Result<RunResult, Error> { if args.len() > 1 { return Err(Error::new( ErrorKind::InvalidInput, @@ -75,17 +70,39 @@ fn cd(args: &[String], home: &PathBuf) -> Result<PathBuf, Error> { )); } - if args.len() == 0 { - return Ok(home.to_path_buf()); - } - - let root = match std::fs::canonicalize(Path::new(args[0].as_str())) { - Ok(p) => p, - Err(_) => Path::new("/").to_path_buf(), + let root = if args.len() == 0 { + home.to_path_buf() + } else { + std::fs::canonicalize(Path::new(args[0].as_str()))? }; match std::env::set_current_dir(&root) { - Ok(_) => Ok(root.to_path_buf()), + Ok(_) => { + *cwd = root; + Ok(RunResult::Builtin) + } Err(e) => Err(e), } } + +fn set(args: &[String]) -> Result<RunResult, Error> { + if args.len() != 2 { + return Err(Error::new( + ErrorKind::InvalidInput, + format!("set requires 2 arguments, got {}", args.len()), + )); + } + std::env::set_var(&args[0], &args[1]); + Ok(RunResult::Builtin) +} + +fn unset(args: &[String]) -> Result<RunResult, Error> { + if args.len() != 1 { + return Err(Error::new( + ErrorKind::InvalidInput, + format!("unset requires 1 argument, got {}", args.len()), + )); + } + std::env::remove_var(&args[0]); + Ok(RunResult::Builtin) +} |