Unify execute_command across platforms
use std::process::Command;
use std::sync::{Arc, Mutex};
use std::io;
+use std::io::Write;
/// Executes a command.
-#[cfg(not(unix))]
pub fn execute_command(mut cmd: Command, out_perm: Arc<Mutex<()>>) {
- use std::process::Stdio;
- use std::io::Write;
-
// Spawn the supplied command.
- let output = cmd.stdout(Stdio::piped()).stderr(Stdio::piped()).output();
+ let output = cmd.output();
// Then wait for the command to exit, if it was spawned.
match output {
Ok(output) => {
// While this lock is active, this thread will be the only thread allowed
- // to write it's outputs.
+ // to write its outputs.
let _lock = out_perm.lock().unwrap();
let stdout = io::stdout();
@@ -41,70 +38,3 @@ pub fn execute_command(mut cmd: Command, out_perm: Arc<Mutex<()>>) {
}
}
}
-
-/// Executes a command.
-#[cfg(all(unix))]
-pub fn execute_command(mut cmd: Command, out_perm: Arc<Mutex<()>>) {
- use libc::{close, dup2, pipe, STDERR_FILENO, STDOUT_FILENO};
- use std::fs::File;
- use std::os::unix::process::CommandExt;
- use std::os::unix::io::FromRawFd;
-
- // Initial a pair of pipes that will be used to
- // pipe the std{out,err} of the spawned process.
- let mut stdout_fds = [0; 2];
- let mut stderr_fds = [0; 2];
-
- unsafe {
- pipe(stdout_fds.as_mut_ptr());
- pipe(stderr_fds.as_mut_ptr());
- }
-
- // Configure the pipes accordingly in the child.
- let child = cmd.before_exec(move || unsafe {
- // Redirect the child's std{out,err} to the write ends of our pipe.
- dup2(stdout_fds[1], STDOUT_FILENO);
- dup2(stderr_fds[1], STDERR_FILENO);
-
- // Close all the fds we created here, so EOF will be sent when the program exits.
- close(stdout_fds[0]);
- close(stdout_fds[1]);
- close(stderr_fds[0]);
- close(stderr_fds[1]);
- Ok(())
- }).spawn();
-
- // Open the read end of the pipes as `File`s.
- let (mut pout, mut perr) = unsafe {
- // Close the write ends of the pipes in the parent
- close(stdout_fds[1]);
- close(stderr_fds[1]);
- (
- // But create files from the read ends.
- File::from_raw_fd(stdout_fds[0]),
- File::from_raw_fd(stderr_fds[0]),
- )
- };
-
- match child {
- Ok(mut child) => {
- let _ = child.wait();
-
- // Create a lock to ensure that this thread has exclusive access to writing.
- let _lock = out_perm.lock().unwrap();
-
- // And then write the outputs of the process until EOF is sent to each file.
- let stdout = io::stdout();
- let stderr = io::stderr();
- let _ = io::copy(&mut pout, &mut stdout.lock());
- let _ = io::copy(&mut perr, &mut stderr.lock());
- }
- Err(why) => {
- if why.kind() == io::ErrorKind::NotFound {
- eprintln!("fd: execution error: command not found");
- } else {
- eprintln!("fd: execution error: {}", why);
- }
- }
- }
-}
