mirror of
https://github.com/CompeyDev/lune-packaging.git
synced 2025-01-11 04:59:11 +00:00
74 lines
2.1 KiB
Rust
74 lines
2.1 KiB
Rust
// https://stackoverflow.com/questions/71141122/-
|
|
|
|
use std::{
|
|
io,
|
|
io::Write,
|
|
process::{Child, ExitStatus},
|
|
};
|
|
|
|
use mlua::prelude::*;
|
|
|
|
pub struct TeeWriter<'a, W0: Write, W1: Write> {
|
|
w0: &'a mut W0,
|
|
w1: &'a mut W1,
|
|
}
|
|
|
|
impl<'a, W0: Write, W1: Write> TeeWriter<'a, W0, W1> {
|
|
pub fn new(w0: &'a mut W0, w1: &'a mut W1) -> Self {
|
|
Self { w0, w1 }
|
|
}
|
|
}
|
|
|
|
impl<'a, W0: Write, W1: Write> Write for TeeWriter<'a, W0, W1> {
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
// We have to use write_all() otherwise what
|
|
// happens if different amounts are written?
|
|
self.w0.write_all(buf)?;
|
|
self.w1.write_all(buf)?;
|
|
Ok(buf.len())
|
|
}
|
|
|
|
fn flush(&mut self) -> io::Result<()> {
|
|
self.w0.flush()?;
|
|
self.w1.flush()?;
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub fn pipe_and_inherit_child_process_stdio(
|
|
mut child: Child,
|
|
) -> LuaResult<(ExitStatus, Vec<u8>, Vec<u8>)> {
|
|
// https://stackoverflow.com/questions/71141122/-
|
|
let mut child_stdout = child.stdout.take().unwrap();
|
|
let mut child_stderr = child.stderr.take().unwrap();
|
|
std::thread::scope(|s| {
|
|
let stdout_thread = s.spawn(|| {
|
|
let stdout = io::stdout();
|
|
let mut log = Vec::new();
|
|
let mut stdout = stdout.lock();
|
|
let mut tee = TeeWriter::new(&mut stdout, &mut log);
|
|
|
|
io::copy(&mut child_stdout, &mut tee).map_err(LuaError::external)?;
|
|
|
|
Ok(log)
|
|
});
|
|
|
|
let stderr_thread = s.spawn(|| {
|
|
let stderr = io::stderr();
|
|
let mut log = Vec::new();
|
|
let mut stderr = stderr.lock();
|
|
let mut tee = TeeWriter::new(&mut stderr, &mut log);
|
|
|
|
io::copy(&mut child_stderr, &mut tee).map_err(LuaError::external)?;
|
|
|
|
Ok(log)
|
|
});
|
|
|
|
let status = child.wait().expect("child wasn't running");
|
|
|
|
let stdout_log: Result<_, LuaError> = stdout_thread.join().expect("stdout thread panicked");
|
|
let stderr_log: Result<_, LuaError> = stderr_thread.join().expect("stderr thread panicked");
|
|
|
|
Ok::<_, LuaError>((status, stdout_log?, stderr_log?))
|
|
})
|
|
}
|