diff options
author | Melody Horn <melody@boringcactus.com> | 2021-03-27 16:52:10 -0600 |
---|---|---|
committer | Melody Horn <melody@boringcactus.com> | 2021-03-27 16:52:10 -0600 |
commit | 66e8fae975a96033277ba7341f7ad40912de1b41 (patch) | |
tree | d352224d8465cbb4e0e531edb4a4fb1356056305 /src/makefile/command_line.rs | |
parent | 85e827763e6c47bb7a15bf04ddc1d15924a746ca (diff) | |
download | makers-66e8fae975a96033277ba7341f7ad40912de1b41.tar.gz makers-66e8fae975a96033277ba7341f7ad40912de1b41.zip |
call the shell explicitly
system is cool and all but unsafe is suboptimal here
Diffstat (limited to 'src/makefile/command_line.rs')
-rw-r--r-- | src/makefile/command_line.rs | 30 |
1 files changed, 24 insertions, 6 deletions
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 |