use io;
use path::Path;
use str;
-use sys::pipe::AnonPipe;
+use sys::pipe::{read2, AnonPipe};
use sys::process as imp;
use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
-use thread::{self, JoinHandle};
/// Representation of a running or exited child process.
///
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
+ fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
+ self.inner.read_to_end(buf)
+ }
}
impl AsInner<AnonPipe> for ChildStdout {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
+ fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
+ self.inner.read_to_end(buf)
+ }
}
impl AsInner<AnonPipe> for ChildStderr {
/// By default, stdin, stdout and stderr are inherited from the parent.
#[stable(feature = "process", since = "1.0.0")]
pub fn spawn(&mut self) -> io::Result<Child> {
- self.inner.spawn(imp::Stdio::Inherit).map(Child::from_inner)
+ self.inner.spawn(imp::Stdio::Inherit, true).map(Child::from_inner)
}
/// Executes the command as a child process, waiting for it to finish and
/// ```
#[stable(feature = "process", since = "1.0.0")]
pub fn output(&mut self) -> io::Result<Output> {
- self.inner.spawn(imp::Stdio::MakePipe).map(Child::from_inner)
+ self.inner.spawn(imp::Stdio::MakePipe, false).map(Child::from_inner)
.and_then(|p| p.wait_with_output())
}
/// ```
#[stable(feature = "process", since = "1.0.0")]
pub fn status(&mut self) -> io::Result<ExitStatus> {
- self.spawn().and_then(|mut p| p.wait())
+ self.inner.spawn(imp::Stdio::Inherit, true).map(Child::from_inner)
+ .and_then(|mut p| p.wait())
}
}
#[stable(feature = "process", since = "1.0.0")]
pub fn wait_with_output(mut self) -> io::Result<Output> {
drop(self.stdin.take());
- fn read<R>(mut input: R) -> JoinHandle<io::Result<Vec<u8>>>
- where R: Read + Send + 'static
- {
- thread::spawn(move || {
- let mut ret = Vec::new();
- input.read_to_end(&mut ret).map(|_| ret)
- })
+
+ let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
+ match (self.stdout.take(), self.stderr.take()) {
+ (None, None) => {}
+ (Some(mut out), None) => {
+ let res = out.read_to_end(&mut stdout);
+ res.unwrap();
+ }
+ (None, Some(mut err)) => {
+ let res = err.read_to_end(&mut stderr);
+ res.unwrap();
+ }
+ (Some(out), Some(err)) => {
+ let res = read2(out.inner, &mut stdout, err.inner, &mut stderr);
+ res.unwrap();
+ }
}
- let stdout = self.stdout.take().map(read);
- let stderr = self.stderr.take().map(read);
- let status = try!(self.wait());
- let stdout = stdout.and_then(|t| t.join().unwrap().ok());
- let stderr = stderr.and_then(|t| t.join().unwrap().ok());
+ let status = self.wait()?;
Ok(Output {
status: status,
- stdout: stdout.unwrap_or(Vec::new()),
- stderr: stderr.unwrap_or(Vec::new()),
+ stdout: stdout,
+ stderr: stderr,
})
}
}