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.rs84
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 })
}