diff options
| -rw-r--r-- | Cargo.lock | 1 | ||||
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | src/makefile/command_line.rs | 30 | 
3 files changed, 24 insertions, 8 deletions
@@ -128,7 +128,6 @@ name = "makers"  version = "0.1.0"  dependencies = [   "lazy_static", - "libc",   "nom",   "regex",   "structopt", @@ -12,7 +12,6 @@ categories = ["development-tools"]  [dependencies]  lazy_static = "1.4.0" -libc = "0.2.91"  nom = "6.1.2"  regex = "1.4.5"  structopt = "0.3.21" diff --git a/src/makefile/command_line.rs b/src/makefile/command_line.rs index 0e0e745..9cc0b8e 100644 --- a/src/makefile/command_line.rs +++ b/src/makefile/command_line.rs @@ -1,9 +1,30 @@ +use std::env;  use std::fmt; +use std::io; +use std::process::{Command, ExitStatus};  use crate::makefile::target::Target;  use crate::makefile::token::{Token, TokenString};  use crate::makefile::Makefile; +// inspired by python's subprocess module +fn execute_command_line(command_line: &str, ignore_errors: bool) -> Result<ExitStatus, io::Error> { +    let (program, args) = if cfg!(windows) { +        let cmd = env::var("COMSPEC").unwrap_or("cmd.exe".into()); +        let args = vec!["/c", command_line]; +        (cmd, args) +    } else { +        let sh = env::var("SHELL").unwrap_or("/bin/sh".into()); +        let args = if ignore_errors { +            vec!["-c", command_line] +        } else { +            vec!["-e", "-c", command_line] +        }; +        (sh, args) +    }; +    Command::new(program).args(args).status() +} +  #[derive(PartialEq, Eq, Clone, Debug)]  pub struct CommandLine {      /// If the command prefix contains a <hyphen-minus>, or the -i option is present, or @@ -68,12 +89,9 @@ impl CommandLine {              return;          } -        // TODO don't fuck this up -        let execution_line = ::std::ffi::CString::new(execution_line.as_bytes()) -            .expect("execution line shouldn't have a null in the middle"); -        // TODO pass shell "-e" if errors are not ignored -        let return_value = unsafe { libc::system(execution_line.as_ptr()) }; -        if return_value != 0 { +        let return_value = execute_command_line(&execution_line, ignore_error); +        let errored = return_value.map_or(true, |status| !status.success()); +        if errored {              // apparently there was an error. do we care?              if !ignore_error {                  // TODO handle this error gracefully  |