diff options
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/process.rs | 10 | ||||
| -rw-r--r-- | library/std/src/sys/unix/pipe.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/unix/process/process_fuchsia.rs | 5 | ||||
| -rw-r--r-- | library/std/src/sys/unix/process/process_unix.rs | 5 | ||||
| -rw-r--r-- | library/std/src/sys/unix/process/process_unsupported.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/unix/process/process_vxworks.rs | 5 | ||||
| -rw-r--r-- | library/std/src/sys/unsupported/pipe.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/unsupported/process.rs | 4 | ||||
| -rw-r--r-- | library/std/src/sys/windows/pipe.rs | 6 | ||||
| -rw-r--r-- | library/std/src/sys/windows/process.rs | 5 | ||||
| -rw-r--r-- | library/std/src/sys_common/process.rs | 31 |
11 files changed, 77 insertions, 6 deletions
diff --git a/library/std/src/process.rs b/library/std/src/process.rs index 400d25beb26..17aff342c15 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -362,6 +362,10 @@ impl Read for ChildStdout { fn is_read_vectored(&self) -> bool { self.inner.is_read_vectored() } + + fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { + self.inner.read_to_end(buf) + } } impl AsInner<AnonPipe> for ChildStdout { @@ -907,10 +911,8 @@ impl Command { /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn output(&mut self) -> io::Result<Output> { - self.inner - .spawn(imp::Stdio::MakePipe, false) - .map(Child::from_inner) - .and_then(|p| p.wait_with_output()) + let (status, stdout, stderr) = self.inner.output()?; + Ok(Output { status: ExitStatus(status), stdout, stderr }) } /// Executes a command as a child process, waiting for it to finish and diff --git a/library/std/src/sys/unix/pipe.rs b/library/std/src/sys/unix/pipe.rs index a56c275c942..a744d0ab640 100644 --- a/library/std/src/sys/unix/pipe.rs +++ b/library/std/src/sys/unix/pipe.rs @@ -58,6 +58,10 @@ impl AnonPipe { self.0.is_read_vectored() } + pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> { + self.0.read_to_end(buf) + } + pub fn write(&self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) } diff --git a/library/std/src/sys/unix/process/process_fuchsia.rs b/library/std/src/sys/unix/process/process_fuchsia.rs index 66ea3db2015..4c99d758c93 100644 --- a/library/std/src/sys/unix/process/process_fuchsia.rs +++ b/library/std/src/sys/unix/process/process_fuchsia.rs @@ -35,6 +35,11 @@ impl Command { Ok((Process { handle: Handle::new(process_handle) }, ours)) } + pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> { + let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?; + crate::sys_common::process::wait_with_output(proc, pipes) + } + pub fn exec(&mut self, default: Stdio) -> io::Error { if self.saw_nul() { return io::const_io_error!( diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index c0716a089bc..39d1c8b1d8e 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -133,6 +133,11 @@ impl Command { } } + pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> { + let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?; + crate::sys_common::process::wait_with_output(proc, pipes) + } + // Attempts to fork the process. If successful, returns Ok((0, -1)) // in the child, and Ok((child_pid, -1)) in the parent. #[cfg(not(target_os = "linux"))] diff --git a/library/std/src/sys/unix/process/process_unsupported.rs b/library/std/src/sys/unix/process/process_unsupported.rs index 72f9f3f9ca7..f28ca58d020 100644 --- a/library/std/src/sys/unix/process/process_unsupported.rs +++ b/library/std/src/sys/unix/process/process_unsupported.rs @@ -20,6 +20,10 @@ impl Command { unsupported() } + pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> { + unsupported() + } + pub fn exec(&mut self, _default: Stdio) -> io::Error { unsupported_err() } diff --git a/library/std/src/sys/unix/process/process_vxworks.rs b/library/std/src/sys/unix/process/process_vxworks.rs index 200ef671967..f549d37c301 100644 --- a/library/std/src/sys/unix/process/process_vxworks.rs +++ b/library/std/src/sys/unix/process/process_vxworks.rs @@ -108,6 +108,11 @@ impl Command { } } + pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> { + let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?; + crate::sys_common::process::wait_with_output(proc, pipes) + } + pub fn exec(&mut self, default: Stdio) -> io::Error { let ret = Command::spawn(self, default, false); match ret { diff --git a/library/std/src/sys/unsupported/pipe.rs b/library/std/src/sys/unsupported/pipe.rs index 25514c2322f..0bba673b458 100644 --- a/library/std/src/sys/unsupported/pipe.rs +++ b/library/std/src/sys/unsupported/pipe.rs @@ -15,6 +15,10 @@ impl AnonPipe { self.0 } + pub fn read_to_end(&self, _buf: &mut Vec<u8>) -> io::Result<usize> { + self.0 + } + pub fn write(&self, _buf: &[u8]) -> io::Result<usize> { self.0 } diff --git a/library/std/src/sys/unsupported/process.rs b/library/std/src/sys/unsupported/process.rs index 633f17c054b..a494f2d6b4c 100644 --- a/library/std/src/sys/unsupported/process.rs +++ b/library/std/src/sys/unsupported/process.rs @@ -75,6 +75,10 @@ impl Command { ) -> io::Result<(Process, StdioPipes)> { unsupported() } + + pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> { + unsupported() + } } impl From<AnonPipe> for Stdio { diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs index 9f26acc4520..7b25edaa556 100644 --- a/library/std/src/sys/windows/pipe.rs +++ b/library/std/src/sys/windows/pipe.rs @@ -1,7 +1,7 @@ use crate::os::windows::prelude::*; use crate::ffi::OsStr; -use crate::io::{self, IoSlice, IoSliceMut}; +use crate::io::{self, IoSlice, IoSliceMut, Read}; use crate::mem; use crate::path::Path; use crate::ptr; @@ -261,6 +261,10 @@ impl AnonPipe { self.inner.is_read_vectored() } + pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> { + self.handle().read_to_end(buf) + } + pub fn write(&self, buf: &[u8]) -> io::Result<usize> { unsafe { let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD; diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index 31e9b34fb9e..10bc949e1f4 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -351,6 +351,11 @@ impl Command { )) } } + + pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> { + let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?; + crate::sys_common::process::wait_with_output(proc, pipes) + } } impl fmt::Debug for Command { diff --git a/library/std/src/sys_common/process.rs b/library/std/src/sys_common/process.rs index 9f978789a62..ae11412067b 100644 --- a/library/std/src/sys_common/process.rs +++ b/library/std/src/sys_common/process.rs @@ -4,7 +4,9 @@ use crate::collections::BTreeMap; use crate::env; use crate::ffi::{OsStr, OsString}; -use crate::sys::process::EnvKey; +use crate::io; +use crate::sys::pipe::read2; +use crate::sys::process::{EnvKey, ExitStatus, Process, StdioPipes}; // Stores a set of changes to an environment #[derive(Clone, Debug)] @@ -117,3 +119,30 @@ impl<'a> ExactSizeIterator for CommandEnvs<'a> { self.iter.is_empty() } } + +pub fn wait_with_output( + mut process: Process, + mut pipes: StdioPipes, +) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> { + drop(pipes.stdin.take()); + + let (mut stdout, mut stderr) = (Vec::new(), Vec::new()); + match (pipes.stdout.take(), pipes.stderr.take()) { + (None, None) => {} + (Some(out), None) => { + let res = out.read_to_end(&mut stdout); + res.unwrap(); + } + (None, Some(err)) => { + let res = err.read_to_end(&mut stderr); + res.unwrap(); + } + (Some(out), Some(err)) => { + let res = read2(out, &mut stdout, err, &mut stderr); + res.unwrap(); + } + } + + let status = process.wait()?; + Ok((status, stdout, stderr)) +} |
