diff --git a/coreutils/src/commands/env.rs b/coreutils/src/commands/env.rs new file mode 100644 index 0000000..11de7ab --- /dev/null +++ b/coreutils/src/commands/env.rs @@ -0,0 +1,78 @@ +use boxutils::args::ArgParser; +use boxutils::commands::Command; + +// note(teesh): this command uses technically unsafe stuff, +// +// HOWEVER: the rust docs state that if you are +// running the things we're doing on a single-threaded +// application (which rebox, and env are), then you +// are fine! + +pub struct Env; + +impl Env { + pub fn clean_unwanted(to_clean: Vec) { + for var in to_clean { + unsafe { + std::env::remove_var(var); + } + } + } + + pub fn maybe_clean_env(maybe: bool) { + if !maybe { + return; + } + + Env::clean_unwanted(std::env::vars().map(|(x, _)| x).collect()); + } + + pub fn print_all_vars() { + for (k, v) in std::env::vars() { + println!("{}={}", k, v); + } + } +} + +impl Command for Env { + fn execute(&self) { + let args = ArgParser::builder() + .add_flag("-i") + .add_flag("-0") + .add_option_list("-u") + .set_seperator("--") + .parse_args("env"); + + let remove_from_env: Vec = args + .get_option_list("-u") + .unwrap_or_default() + .iter() + .map(|a| a.to_string()) + .collect(); + let null_terminate = args.get_flag("-0"); + let clean_env = args.get_flag("-i") | args.get_flag("-"); + let to_run = args.get_normal_args(); + + Env::clean_unwanted(remove_from_env); + Env::maybe_clean_env(clean_env); + + if to_run.is_empty() { + Env::print_all_vars(); + + return; + } + + if let Some((command, args)) = to_run.split_first() { + std::process::Command::new(command) + .args(args) + .spawn() + .expect("env: failed to start command") + .wait() + .expect("env: could not wait for command"); + } + + if null_terminate { + print!("\0"); + } + } +} diff --git a/coreutils/src/commands/mod.rs b/coreutils/src/commands/mod.rs index 3ada810..9345846 100644 --- a/coreutils/src/commands/mod.rs +++ b/coreutils/src/commands/mod.rs @@ -23,3 +23,4 @@ command!(tee::Tee); command!(base64::Base64); command!(base32::Base32); command!(seq::Seq); +command!(env::Env); \ No newline at end of file diff --git a/src/registry.rs b/src/registry.rs index 04d6b83..80bac2f 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -33,6 +33,7 @@ pub fn get_registry() -> CommandRegistry { "base64" => coreutils::commands::Base64, "base32" => coreutils::commands::Base32, "seq" => coreutils::commands::Seq, + "env" => coreutils::commands::Env, "box" => Boxcmd });