diff --git a/Cargo.lock b/Cargo.lock index b4bbf77..82b190c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,4 +19,12 @@ version = "0.1.0" dependencies = [ "boxutils", "coreutils", + "shell", +] + +[[package]] +name = "shell" +version = "0.1.0" +dependencies = [ + "boxutils", ] diff --git a/Cargo.toml b/Cargo.toml index 95d6c0c..43e4058 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2024" [dependencies] boxutils = { path = "./utils" } coreutils = { path = "./coreutils" } +shell = { path = "./shell" } [[bin]] diff --git a/shell/Cargo.toml b/shell/Cargo.toml new file mode 100644 index 0000000..10deedd --- /dev/null +++ b/shell/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "shell" +version = "0.1.0" +edition = "2024" + +[dependencies] +boxutils = { path = "../utils" } diff --git a/shell/src/ash.rs b/shell/src/ash.rs new file mode 100644 index 0000000..d246d62 --- /dev/null +++ b/shell/src/ash.rs @@ -0,0 +1,56 @@ +use boxutils::commands::Command; +use std::env; +use std::process::Command as stdCommand; +use std::io::{self, Write, ErrorKind}; +use std::path::Path; +use std::fmt; + +pub struct Ash; + +impl Command for Ash { + fn execute(&self) { + loop { + let path = env::current_dir(); + print!( + "{} $ ", // TODO: display "#" if root + path.expect("unknown").display() + ); + let _ = io::stdout().flush(); + let mut input = String::new(); + io::stdin().read_line(&mut input).unwrap(); + let mut full_cmd = input.trim().split_whitespace(); + let command = full_cmd.next().unwrap(); + let mut arguments = full_cmd; + match command { + "exit" => return, + "cd" => { + let new_path = arguments.next(); + let new_path = Path::new(new_path.unwrap()); + let _ = env::set_current_dir(&new_path).is_ok(); + }, + command => { + let out = stdCommand::new(command) + .args(arguments) + .spawn(); + + match out { + Ok(mut out) => { + let _ = out.wait(); + }, + Err(err) => match err.kind() { + ErrorKind::NotFound => { + eprintln!("ash: {}: not found", command); + } + ErrorKind::PermissionDenied => { + eprintln!("ash: {}: permission denied", command); + } + _ => { + eprintln!("ash: uncaught error: {}", err); + } + } + } + }, + } + } + } +} diff --git a/shell/src/lib.rs b/shell/src/lib.rs new file mode 100644 index 0000000..0f1b7be --- /dev/null +++ b/shell/src/lib.rs @@ -0,0 +1 @@ +pub mod ash; diff --git a/src/registry.rs b/src/registry.rs index 143ab62..130d127 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -8,6 +8,7 @@ pub fn get_registry() -> CommandRegistry { registry.register("cat", Box::new(coreutils::commands::Cat)); registry.register("echo", Box::new(coreutils::commands::Echo)); registry.register("mkdir", Box::new(coreutils::commands::Mkdir)); + registry.register("ash", Box::new(shell::ash::Ash)); registry.register("box", Box::new(Boxcmd)); registry