aboutsummaryrefslogtreecommitdiff
path: root/src/parser/command.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/command.rs')
-rw-r--r--src/parser/command.rs59
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)
+}