Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/stdx/src/process.rs')
| -rw-r--r-- | crates/stdx/src/process.rs | 84 |
1 files changed, 48 insertions, 36 deletions
diff --git a/crates/stdx/src/process.rs b/crates/stdx/src/process.rs index b26b71c9de..e5aa343651 100644 --- a/crates/stdx/src/process.rs +++ b/crates/stdx/src/process.rs @@ -5,54 +5,66 @@ use std::{ io, - process::{Command, Output, Stdio}, + process::{ChildStderr, ChildStdout, Command, Output, Stdio}, }; +use crate::JodChild; + pub fn streaming_output( - mut cmd: Command, + out: ChildStdout, + err: ChildStderr, on_stdout_line: &mut dyn FnMut(&str), on_stderr_line: &mut dyn FnMut(&str), -) -> io::Result<Output> { +) -> io::Result<(Vec<u8>, Vec<u8>)> { let mut stdout = Vec::new(); let mut stderr = Vec::new(); - let cmd = cmd.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null()); - - let status = { - let mut child = cmd.spawn()?; - let out = child.stdout.take().unwrap(); - let err = child.stderr.take().unwrap(); - imp::read2(out, err, &mut |is_out, data, eof| { - let idx = if eof { - data.len() - } else { - match data.iter().rposition(|b| *b == b'\n') { - Some(i) => i + 1, - None => return, - } + imp::read2(out, err, &mut |is_out, data, eof| { + let idx = if eof { + data.len() + } else { + match data.iter().rposition(|b| *b == b'\n') { + Some(i) => i + 1, + None => return, + } + }; + { + // scope for new_lines + let new_lines = { + let dst = if is_out { &mut stdout } else { &mut stderr }; + let start = dst.len(); + let data = data.drain(..idx); + dst.extend(data); + &dst[start..] }; - { - // scope for new_lines - let new_lines = { - let dst = if is_out { &mut stdout } else { &mut stderr }; - let start = dst.len(); - let data = data.drain(..idx); - dst.extend(data); - &dst[start..] - }; - for line in String::from_utf8_lossy(new_lines).lines() { - if is_out { - on_stdout_line(line); - } else { - on_stderr_line(line); - } + for line in String::from_utf8_lossy(new_lines).lines() { + if is_out { + on_stdout_line(line); + } else { + on_stderr_line(line); } } - })?; - let _ = child.kill(); - child.wait()? - }; + } + })?; + + Ok((stdout, stderr)) +} + +pub fn spawn_with_streaming_output( + mut cmd: Command, + on_stdout_line: &mut dyn FnMut(&str), + on_stderr_line: &mut dyn FnMut(&str), +) -> io::Result<Output> { + let cmd = cmd.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null()); + let mut child = JodChild(cmd.spawn()?); + let (stdout, stderr) = streaming_output( + child.stdout.take().unwrap(), + child.stderr.take().unwrap(), + on_stdout_line, + on_stderr_line, + )?; + let status = child.wait()?; Ok(Output { status, stdout, stderr }) } |