From e4db4e8a2f7b3e48105ff0b298aa32f1566cd511 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Fri, 19 Jan 2018 20:53:36 -0500 Subject: [PATCH] Create an asynccmd for running Commands in the background --- ofborg/src/asynccmd.rs | 83 ++++++++++++++++++++++++++++++++++++++++++ ofborg/src/lib.rs | 3 +- 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 ofborg/src/asynccmd.rs diff --git a/ofborg/src/asynccmd.rs b/ofborg/src/asynccmd.rs new file mode 100644 index 0000000..c41ecd2 --- /dev/null +++ b/ofborg/src/asynccmd.rs @@ -0,0 +1,83 @@ +use std::thread; + +use std::process::Stdio; +use std::process::ExitStatus; +use std::sync::mpsc::channel; +use std::process::Command; +use std::io::Read; +use std::sync::mpsc::{Sender,Receiver}; +use std::io::BufReader; +use std::io::BufRead; +use std::process::Child; +use std::thread::JoinHandle; + +pub struct AsyncCmd { + command: Command, +} + +pub struct SpawnedAsyncCmd { + stdout_handler: JoinHandle<()>, + stderr_handler: JoinHandle<()>, + child: Child, + rx: Receiver, +} + + +fn reader_tx(read: R, tx: Sender) -> thread::JoinHandle<()> { + let read = BufReader::new(read); + + thread::spawn(move|| { + for line in read.lines() { + if let Ok(line) = line { + // println!("sending: {:?}", line); + tx.send(line).expect("Failed to send log line"); + } else { + println!("Got in reader tx's else: {:?}", line); + } + } + }) +} + +impl AsyncCmd { + pub fn new(cmd: Command) -> AsyncCmd { + AsyncCmd { + command: cmd, + } + } + + pub fn spawn(mut self) -> SpawnedAsyncCmd { + let mut child = self.command + .stdin(Stdio::null()) + .stderr(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .unwrap(); + + let (tx, rx) = channel(); + + let stderr_handler = reader_tx(child.stderr.take().unwrap(), + tx.clone()); + let stdout_handler = reader_tx(child.stdout.take().unwrap(), + tx.clone()); + + SpawnedAsyncCmd { + stdout_handler: stdout_handler, + stderr_handler: stderr_handler, + child: child, + rx: rx, + } + } +} + +impl SpawnedAsyncCmd { + pub fn lines<'a>(&'a mut self) -> &'a Receiver { + &self.rx + } + pub fn wait(mut self) -> ExitStatus { + let status = self.child.wait(); + self.stdout_handler.join().unwrap(); + self.stderr_handler.join().unwrap(); + + return status.unwrap(); + } +} diff --git a/ofborg/src/lib.rs b/ofborg/src/lib.rs index 39d73ff..3295e48 100644 --- a/ofborg/src/lib.rs +++ b/ofborg/src/lib.rs @@ -30,9 +30,10 @@ pub mod commentparser; pub mod commitstatus; pub mod outpathdiff; pub mod tagger; - +pub mod asynccmd; pub mod ofborg { + pub use asynccmd; pub use config; pub use checkout; pub use locks;