blob: a8f2f35f0798ac476c4d8e97de86e9b599e3a52d [file] [log] [blame]
use std::io::{Read, Write};
use std::process::{Command, Stdio};
use std::rc::Rc;
use futures::Poll;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio_process::{Child, CommandExt};
pub struct ChildProcess {
stdin: tokio_process::ChildStdin,
stdout: tokio_process::ChildStdout,
child: Rc<tokio_process::Child>,
}
impl Read for ChildProcess {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
Read::read(&mut self.stdout, buf)
}
}
impl Write for ChildProcess {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
Write::write(&mut self.stdin, buf)
}
fn flush(&mut self) -> std::io::Result<()> {
Write::flush(&mut self.stdin)
}
}
impl AsyncRead for ChildProcess {}
impl AsyncWrite for ChildProcess {
fn shutdown(&mut self) -> Poll<(), std::io::Error> {
AsyncWrite::shutdown(&mut self.stdin)
}
}
impl ChildProcess {
pub fn spawn_from_command(mut cmd: Command) -> Result<ChildProcess, std::io::Error> {
cmd.stdin(Stdio::piped());
cmd.stdout(Stdio::piped());
let mut child = cmd.spawn_async()?;
Ok(ChildProcess {
stdout: child.stdout().take().unwrap(),
stdin: child.stdin().take().unwrap(),
child: Rc::new(child),
})
}
/// Returns a handle to the underlying `Child` process.
/// Useful when waiting until child process exits.
pub fn child(&self) -> Rc<Child> {
Rc::clone(&self.child)
}
}