Auto merge of #29897 - alexcrichton:process-wait-with-output, r=brson
Previously this function used channels but this isn't necessary any more now that threads have return values. This also has the added bonus of appropriately waiting for the thread to exit to ensure that the function doesn't still have running threads once it returns.
This commit is contained in:
commit
8ed8679b2e
1 changed files with 14 additions and 20 deletions
|
@ -20,11 +20,10 @@ use ffi::OsStr;
|
||||||
use fmt;
|
use fmt;
|
||||||
use io::{self, Error, ErrorKind};
|
use io::{self, Error, ErrorKind};
|
||||||
use path;
|
use path;
|
||||||
use sync::mpsc::{channel, Receiver};
|
|
||||||
use sys::pipe::{self, AnonPipe};
|
use sys::pipe::{self, AnonPipe};
|
||||||
use sys::process as imp;
|
use sys::process as imp;
|
||||||
use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
|
use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
|
||||||
use thread;
|
use thread::{self, JoinHandle};
|
||||||
|
|
||||||
/// Representation of a running or exited child process.
|
/// Representation of a running or exited child process.
|
||||||
///
|
///
|
||||||
|
@ -542,29 +541,24 @@ impl Child {
|
||||||
#[stable(feature = "process", since = "1.0.0")]
|
#[stable(feature = "process", since = "1.0.0")]
|
||||||
pub fn wait_with_output(mut self) -> io::Result<Output> {
|
pub fn wait_with_output(mut self) -> io::Result<Output> {
|
||||||
drop(self.stdin.take());
|
drop(self.stdin.take());
|
||||||
fn read<T: Read + Send + 'static>(stream: Option<T>) -> Receiver<io::Result<Vec<u8>>> {
|
fn read<R>(mut input: R) -> JoinHandle<io::Result<Vec<u8>>>
|
||||||
let (tx, rx) = channel();
|
where R: Read + Send + 'static
|
||||||
match stream {
|
{
|
||||||
Some(stream) => {
|
thread::spawn(move || {
|
||||||
thread::spawn(move || {
|
let mut ret = Vec::new();
|
||||||
let mut stream = stream;
|
input.read_to_end(&mut ret).map(|_| ret)
|
||||||
let mut ret = Vec::new();
|
})
|
||||||
let res = stream.read_to_end(&mut ret);
|
|
||||||
tx.send(res.map(|_| ret)).unwrap();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
None => tx.send(Ok(Vec::new())).unwrap()
|
|
||||||
}
|
|
||||||
rx
|
|
||||||
}
|
}
|
||||||
let stdout = read(self.stdout.take());
|
let stdout = self.stdout.take().map(read);
|
||||||
let stderr = read(self.stderr.take());
|
let stderr = self.stderr.take().map(read);
|
||||||
let status = try!(self.wait());
|
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());
|
||||||
|
|
||||||
Ok(Output {
|
Ok(Output {
|
||||||
status: status,
|
status: status,
|
||||||
stdout: stdout.recv().unwrap().unwrap_or(Vec::new()),
|
stdout: stdout.unwrap_or(Vec::new()),
|
||||||
stderr: stderr.recv().unwrap().unwrap_or(Vec::new()),
|
stderr: stderr.unwrap_or(Vec::new()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue