diff --git a/src/pschdir.rs b/src/pschdir.rs deleted file mode 100644 index eaa7e63..0000000 --- a/src/pschdir.rs +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2023_2024 DTB - * SPDX-License-Identifier: AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify it under - * the terms of the GNU Affero General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more - * details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see https://www.gnu.org/licenses/. - */ - -use std::{ env::args, io::Error, process::{ Command, ExitCode } }; - -extern crate strerror; -use strerror::StrError; - -extern crate sysexits; -use sysexits::{ EX_UNAVAILABLE, EX_USAGE }; - -fn error(p: &str, n: &str, e: Error) -> ExitCode { - eprintln!("{}: {}: {}", p, n, e.strerror()); - ExitCode::from(EX_UNAVAILABLE as u8) -} - -fn main() -> ExitCode { - let argv = args().collect::>(); - - if argv.len() < 3 { - eprintln!("Usage: {} directory command [argument]", argv[0]); - return ExitCode::from(EX_USAGE as u8); - } - - let cmdargs = argv.iter().clone().skip(3).collect::>(); - - match Command::new(argv[2].clone()) - .current_dir(argv[1].clone()) - .args(cmdargs) - .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 - } - } - }, - Err(e) => error(&argv[0], &argv[2], e) - }, - Err(e) => error(&argv[0], &argv[2], e) - } -} diff --git a/src/simexec.rs b/src/simexec.rs index 57a5dc7..282768f 100644 --- a/src/simexec.rs +++ b/src/simexec.rs @@ -23,6 +23,9 @@ use std::{ process::{ Command, ExitCode } }; +extern crate getopt; +use getopt::GetOpt; + extern crate strerror; use strerror::StrError; @@ -34,19 +37,41 @@ fn error(p: &str, n: &str, e: Error) -> ExitCode { ExitCode::from(EX_UNAVAILABLE as u8) } +fn usage(s: &str) -> ExitCode { + eprintln!("Usage: {} command [argument...]"); + ExitCode::from(EX_USAGE as u8) +} + fn main() -> ExitCode { let argv = args().collect::>(); + let mut optind = 0; - if argv.len() < 2 { - eprintln!("Usage: {} binary argv...", argv[0]); - return ExitCode::from(EX_USAGE as u8); + let mut arg0: Option = None; + let mut dir = String::from("."); + + let mut cmd; + + while let Some(opt) = argv.getopt("C:n") { + match opt.opt() { + Ok("C") => dir = opt.arg().unwrap(), + Ok("n") => arg0 = Some(opt.arg().unwrap()), + _ => { return usage(&argv[0]); } + } + optind = opt.ind(); } - let mut cmd = Command::new(argv[1].clone()); + if argv.len() - optind < 1 { return usage(&argv[0]); } - if argv.len() > 2 { cmd.arg0(argv[2].clone()); } - if argv.len() > 3 { - let cmdargs = argv.iter().clone().skip(3).collect::>(); + cmd = Command::new(argv[optind].clone()).current_dir(argv[1].clone()); + + if let Some(a) = arg0 { cmd.arg0(a); } + + if argv.len() - optind > 2 { + let cmdargs = argv + .iter() + .clone() + .skip(optind + 1) + .collect::>(); cmd.args(cmdargs); }