summaryrefslogtreecommitdiffstats
path: root/src/utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils.rs')
-rw-r--r--src/utils.rs31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/utils.rs b/src/utils.rs
index def0a5fa5..b9699af0b 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -1,7 +1,8 @@
use process_control::{ChildExt, Timeout};
+use std::ffi::OsStr;
use std::fmt::Debug;
use std::fs::read_to_string;
-use std::io::Result;
+use std::io::{Error, ErrorKind, Result};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::time::{Duration, Instant};
@@ -23,6 +24,33 @@ pub fn read_file<P: AsRef<Path> + Debug>(file_name: P) -> Result<String> {
result
}
+/// Attempt to resolve `binary_name` from and creates a new `Command` pointing at it
+/// This allows executing cmd files on Windows and prevents running executable from cwd on Windows
+/// This function also initialises std{err,out,in} to protect against processes changing the console mode
+pub fn create_command<T: AsRef<OsStr>>(binary_name: T) -> Result<Command> {
+ let binary_name = binary_name.as_ref();
+ log::trace!("Creating Command struct with binary name {:?}", binary_name);
+
+ let full_path = match which::which(binary_name) {
+ Ok(full_path) => {
+ log::trace!("Using {:?} as {:?}", full_path, binary_name);
+ full_path
+ }
+ Err(error) => {
+ log::trace!("Unable to find {:?} in PATH, {:?}", binary_name, error);
+ return Err(Error::new(ErrorKind::NotFound, error));
+ }
+ };
+
+ #[allow(clippy::disallowed_method)]
+ let mut cmd = Command::new(full_path);
+ cmd.stderr(Stdio::piped())
+ .stdout(Stdio::piped())
+ .stdin(Stdio::null());
+
+ Ok(cmd)
+}
+
#[derive(Debug, Clone)]
pub struct CommandOutput {
pub stdout: String,
@@ -324,6 +352,7 @@ fn internal_exec_cmd(cmd: &str, args: &[&str], time_limit: Duration) -> Option<C
let start = Instant::now();
+ #[allow(clippy::disallowed_method)]
let process = match Command::new(full_path)
.args(args)
.stderr(Stdio::piped())