From 66e8fae975a96033277ba7341f7ad40912de1b41 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Sat, 27 Mar 2021 16:52:10 -0600 Subject: call the shell explicitly system is cool and all but unsafe is suboptimal here --- Cargo.lock | 1 - Cargo.toml | 1 - src/makefile/command_line.rs | 30 ++++++++++++++++++++++++------ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 00bc731..05cc7ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,7 +128,6 @@ name = "makers" version = "0.1.0" dependencies = [ "lazy_static", - "libc", "nom", "regex", "structopt", diff --git a/Cargo.toml b/Cargo.toml index b97dc43..b385dff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 { + 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 , 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 -- cgit v1.2.3