about summary refs log tree commit diff
path: root/library/std/src/sys_common/process.rs
diff options
context:
space:
mode:
authorAyush Singh <ayushsingh1325@gmail.com>2022-12-08 18:22:33 +0530
committerAyush Singh <ayushsingh1325@gmail.com>2022-12-11 10:21:40 +0530
commita94793d8d17e4cfe2e727c30c36e174b8d6b6ee3 (patch)
tree4a6bb73b64331a1ab40165c5c8892bedb1ec837e /library/std/src/sys_common/process.rs
parent5479fe5f70bb32f037ff97de03ed185bdf2f54b7 (diff)
downloadrust-a94793d8d17e4cfe2e727c30c36e174b8d6b6ee3.tar.gz
rust-a94793d8d17e4cfe2e727c30c36e174b8d6b6ee3.zip
Implement blocking output
This allows decoupling `Command::spawn` and `Command::output`. This is
useful for targets which do support launching programs in blocking mode
but do not support multitasking (Eg: UEFI).

This was originally conceived when working on https://github.com/rust-lang/rust/pull/100316

Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
Diffstat (limited to 'library/std/src/sys_common/process.rs')
-rw-r--r--library/std/src/sys_common/process.rs31
1 files changed, 30 insertions, 1 deletions
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))
+}