Skip to content

Commit

Permalink
check builtin/custom spawning thread status
Browse files Browse the repository at this point in the history
change thread handle return type from () to CmdResult
fix #22
  • Loading branch information
tao-guo committed Apr 5, 2021
1 parent 33d9a9d commit fd851a1
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 30 deletions.
53 changes: 30 additions & 23 deletions src/child.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::io::CmdIn;
use crate::CmdResult;
use log::info;
use os_pipe::PipeReader;
use std::io::{BufRead, BufReader, Error, ErrorKind, Read, Result, Write};
use std::io::{self, BufRead, BufReader, Error, ErrorKind, Read, Result, Write};
use std::process::{Child, ExitStatus};
use std::thread::JoinHandle;

Expand All @@ -21,41 +21,55 @@ impl CmdChildHandle {
}
}

pub fn wait(self) -> CmdResult {
pub fn wait(self, is_last: bool) -> CmdResult {
let pipefail = std::env::var("CMD_LIB_PIPEFAIL") != Ok("0".into());
let check_result = |result| {
if let Err(e) = result {
if is_last || pipefail {
return Err(e);
}
}
Ok(())
};
match self {
Self::ProcChild(mut p) => {
let status = p.child.wait()?;
Self::log_stderr(&mut p.child);
if !status.success() && std::env::var("CMD_LIB_PIPEFAIL") != Ok("0".into()) {
if !status.success() && (is_last || pipefail) {
return Err(Self::status_to_io_error(
status,
&format!("{} exited with error", p.cmd),
));
}
Ok(())
}
Self::ThreadChild(t) => {
let status = t.child.join();
if let Err(e) = status {
return Err(Error::new(
ErrorKind::Other,
format!("{} thread exited with error: {:?}", t.cmd, e),
));
match status {
Err(e) => {
if is_last || pipefail {
return Err(Error::new(
ErrorKind::Other,
format!("{} thread exited with error: {:?}", t.cmd, e),
));
}
}
Ok(result) => {
check_result(result)?;
}
}
Ok(())
}
Self::SyncChild(s) => {
if let Some(mut out) = s.output {
let mut buf = vec![];
out.read_to_end(&mut buf)?;
std::io::stdout().write_all(&buf[..])?;
check_result(out.read_to_end(&mut buf).map(|_|()))?;
check_result(io::stdout().write_all(&buf[..]))?;
}
Ok(())
}
}
Ok(())
}

pub fn wait_last_with_output(self) -> Result<Vec<u8>> {
pub fn wait_with_output(self) -> Result<Vec<u8>> {
match self {
Self::ProcChild(p) => {
let output = p.child.wait_with_output()?;
Expand All @@ -70,14 +84,7 @@ impl CmdChildHandle {
}
}
Self::ThreadChild(t) => {
let status = t.child.join();
if let Err(e) = status {
return Err(Error::new(
ErrorKind::Other,
format!("{} thread exited with error: {:?}", t.cmd, e),
));
}
Ok(vec![])
panic!("{} thread should not be waited for output", t.cmd);
}
Self::SyncChild(s) => {
if let Some(mut out) = s.output {
Expand Down Expand Up @@ -132,7 +139,7 @@ pub struct CmdProcChild {
}

pub struct CmdThreadChild {
pub child: JoinHandle<()>,
pub child: JoinHandle<CmdResult>,
pub cmd: String,
pub stderr_logging: Option<CmdIn>,
}
Expand Down
12 changes: 5 additions & 7 deletions src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,14 +227,14 @@ impl WaitCmd {
fn wait_result_nolog(&mut self) -> CmdResult {
// wait last process result
let handle = self.0.pop().unwrap();
handle.wait()?;
handle.wait(true)?;
Self::wait_children(&mut self.0)
}

fn wait_children(children: &mut Vec<CmdChildHandle>) -> CmdResult {
while !children.is_empty() {
let child_handle = children.pop().unwrap();
child_handle.wait()?;
child_handle.wait(false)?;
}
Ok(())
}
Expand All @@ -256,7 +256,7 @@ impl WaitFun {

pub fn wait_raw_result_nolog(&mut self) -> Result<Vec<u8>> {
let handle = self.0.pop().unwrap();
let wait_last = handle.wait_last_with_output();
let wait_last = handle.wait_with_output();
match wait_last {
Err(e) => {
let _ = WaitCmd::wait_children(&mut self.0);
Expand Down Expand Up @@ -284,7 +284,7 @@ impl WaitFun {
pub fn wait_result_nolog(&mut self) -> FunResult {
// wait last process result
let handle = self.0.pop().unwrap();
let wait_last = handle.wait_last_with_output();
let wait_last = handle.wait_with_output();
match wait_last {
Err(e) => {
let _ = WaitCmd::wait_children(&mut self.0);
Expand Down Expand Up @@ -474,9 +474,7 @@ impl Cmd {

let internal_cmd = CMD_MAP.lock().unwrap()[&arg0];
if pipe_out {
let handle = std::thread::spawn(move || {
internal_cmd(&mut env).unwrap();
});
let handle = std::thread::spawn(move || internal_cmd(&mut env));
Ok(CmdChildHandle::ThreadChild(CmdThreadChild {
child: handle,
stderr_logging: self.stderr_logging,
Expand Down

0 comments on commit fd851a1

Please sign in to comment.