aboutsummaryrefslogtreecommitdiff
path: root/src/makefile
diff options
context:
space:
mode:
authorMelody Horn <melody@boringcactus.com>2021-03-27 16:52:10 -0600
committerMelody Horn <melody@boringcactus.com>2021-03-27 16:52:10 -0600
commit66e8fae975a96033277ba7341f7ad40912de1b41 (patch)
treed352224d8465cbb4e0e531edb4a4fb1356056305 /src/makefile
parent85e827763e6c47bb7a15bf04ddc1d15924a746ca (diff)
downloadmakers-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')
-rw-r--r--src/makefile/command_line.rs30
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