From e0f9641e9395484ec6c1c7d49d20d04257526dc0 Mon Sep 17 00:00:00 2001 From: DTB Date: Wed, 24 Jul 2024 23:39:47 -0600 Subject: [PATCH] run(1) works --- src/run.rs | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/run.rs b/src/run.rs index 282768f..9f7b926 100644 --- a/src/run.rs +++ b/src/run.rs @@ -38,23 +38,26 @@ fn error(p: &str, n: &str, e: Error) -> ExitCode { } fn usage(s: &str) -> ExitCode { - eprintln!("Usage: {} command [argument...]"); + eprintln!("Usage: {} command [argument...]", s); ExitCode::from(EX_USAGE as u8) } fn main() -> ExitCode { let argv = args().collect::>(); - let mut optind = 0; + let mut optind = 1; - let mut arg0: Option = None; - let mut dir = String::from("."); + /* arg0 is None if no argv[0] is meant to be given (argc will be 0), + * however I don't know how to do this in Rust, so the option is currently + * meaningless. -z will set this to None. */ + let mut arg0: Option = Some(String::default()); + let mut dir = String::from("."); // $PWD for command - let mut cmd; - - while let Some(opt) = argv.getopt("C:n") { + while let Some(opt) = argv.getopt("C:n:z") { match opt.opt() { + // Consistent with precedent; git, make, tar, etc. Ok("C") => dir = opt.arg().unwrap(), Ok("n") => arg0 = Some(opt.arg().unwrap()), + // Ok("z") => arg0 = None, _ => { return usage(&argv[0]); } } optind = opt.ind(); @@ -62,11 +65,15 @@ fn main() -> ExitCode { if argv.len() - optind < 1 { return usage(&argv[0]); } - cmd = Command::new(argv[optind].clone()).current_dir(argv[1].clone()); + let mut cmd = Command::new(argv[optind].clone()); + cmd.current_dir(dir.clone()); - if let Some(a) = arg0 { cmd.arg0(a); } + match arg0 { + Some(a) if a != String::default() => { cmd.arg0(a); }, + _ => () // TODO: argv[0]==NULL support + } - if argv.len() - optind > 2 { + if argv.len() - optind > 1 { // there are arguments let cmdargs = argv .iter() .clone() @@ -77,18 +84,16 @@ fn main() -> ExitCode { match cmd.spawn() { Ok(mut child) => match child.wait() { - Ok(status) => { - match status.code() { - Some(code) => ExitCode::from(code as u8), - None => { - eprintln!("{}: {}: process terminated by signal", - argv[0], argv[2]); - ExitCode::FAILURE - } + Ok(status) => match status.code() { + Some(code) => ExitCode::from(code as u8), + None => { + eprintln!("{}: {}: process terminated by signal", + argv[0], argv[2]); + ExitCode::FAILURE } }, - Err(e) => error(&argv[0], &argv[2], e) + Err(e) => error(&argv[0], &argv[optind], e) }, - Err(e) => error(&argv[0], &argv[2], e) + Err(e) => error(&argv[0], &argv[optind], e) } }