don't unconfigure stdio streams on spawn
This commit is contained in:
parent
327f176ba4
commit
afff8c533d
53
src/lib.rs
53
src/lib.rs
|
@ -618,9 +618,9 @@ impl io::AsyncRead for ChildStderr {
|
|||
/// ```
|
||||
pub struct Command {
|
||||
inner: std::process::Command,
|
||||
stdin: Option<Stdio>,
|
||||
stdout: Option<Stdio>,
|
||||
stderr: Option<Stdio>,
|
||||
stdin: bool,
|
||||
stdout: bool,
|
||||
stderr: bool,
|
||||
reap_on_drop: bool,
|
||||
kill_on_drop: bool,
|
||||
}
|
||||
|
@ -641,9 +641,9 @@ impl Command {
|
|||
pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
|
||||
Command {
|
||||
inner: std::process::Command::new(program),
|
||||
stdin: None,
|
||||
stdout: None,
|
||||
stderr: None,
|
||||
stdin: false,
|
||||
stdout: false,
|
||||
stderr: false,
|
||||
reap_on_drop: true,
|
||||
kill_on_drop: false,
|
||||
}
|
||||
|
@ -785,7 +785,8 @@ impl Command {
|
|||
/// cmd.stdin(Stdio::null());
|
||||
/// ```
|
||||
pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
|
||||
self.stdin = Some(cfg.into());
|
||||
self.stdin = true;
|
||||
self.inner.stdin(cfg);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -800,7 +801,8 @@ impl Command {
|
|||
/// cmd.stdout(Stdio::piped());
|
||||
/// ```
|
||||
pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
|
||||
self.stdout = Some(cfg.into());
|
||||
self.stdout = true;
|
||||
self.inner.stdout(cfg);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -815,7 +817,8 @@ impl Command {
|
|||
/// cmd.stderr(Stdio::piped());
|
||||
/// ```
|
||||
pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
|
||||
self.stderr = Some(cfg.into());
|
||||
self.stderr = true;
|
||||
self.inner.stderr(cfg);
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -865,8 +868,6 @@ impl Command {
|
|||
///
|
||||
/// If not configured, stdin, stdout and stderr will be set to [`Stdio::inherit()`].
|
||||
///
|
||||
/// After spawning the process, stdin, stdout, and stderr become unconfigured again.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
|
@ -877,10 +878,15 @@ impl Command {
|
|||
/// # std::io::Result::Ok(()) });
|
||||
/// ```
|
||||
pub fn spawn(&mut self) -> io::Result<Child> {
|
||||
let (stdin, stdout, stderr) = (self.stdin.take(), self.stdout.take(), self.stderr.take());
|
||||
self.inner.stdin(stdin.unwrap_or_else(Stdio::inherit));
|
||||
self.inner.stdout(stdout.unwrap_or_else(Stdio::inherit));
|
||||
self.inner.stderr(stderr.unwrap_or_else(Stdio::inherit));
|
||||
if !self.stdin {
|
||||
self.inner.stdin(Stdio::inherit());
|
||||
}
|
||||
if !self.stdout {
|
||||
self.inner.stdout(Stdio::inherit());
|
||||
}
|
||||
if !self.stderr {
|
||||
self.inner.stderr(Stdio::inherit());
|
||||
}
|
||||
|
||||
Child::new(self)
|
||||
}
|
||||
|
@ -889,8 +895,6 @@ impl Command {
|
|||
///
|
||||
/// If not configured, stdin, stdout and stderr will be set to [`Stdio::inherit()`].
|
||||
///
|
||||
/// After spawning the process, stdin, stdout, and stderr become unconfigured again.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
|
@ -914,8 +918,6 @@ impl Command {
|
|||
/// If not configured, stdin will be set to [`Stdio::null()`], and stdout and stderr will be
|
||||
/// set to [`Stdio::piped()`].
|
||||
///
|
||||
/// After spawning the process, stdin, stdout, and stderr become unconfigured again.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
|
@ -929,10 +931,15 @@ impl Command {
|
|||
/// # std::io::Result::Ok(()) });
|
||||
/// ```
|
||||
pub fn output(&mut self) -> impl Future<Output = io::Result<Output>> {
|
||||
let (stdin, stdout, stderr) = (self.stdin.take(), self.stdout.take(), self.stderr.take());
|
||||
self.inner.stdin(stdin.unwrap_or_else(Stdio::null));
|
||||
self.inner.stdout(stdout.unwrap_or_else(Stdio::piped));
|
||||
self.inner.stderr(stderr.unwrap_or_else(Stdio::piped));
|
||||
if !self.stdin {
|
||||
self.inner.stdin(Stdio::null());
|
||||
}
|
||||
if !self.stdout {
|
||||
self.inner.stdout(Stdio::piped());
|
||||
}
|
||||
if !self.stderr {
|
||||
self.inner.stderr(Stdio::piped());
|
||||
}
|
||||
|
||||
let child = Child::new(self);
|
||||
async { child?.output().await }
|
||||
|
|
22
tests/std.rs
22
tests/std.rs
|
@ -407,3 +407,25 @@ fn child_as_raw_handle() {
|
|||
assert_eq!(win_pid, std_pid);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn test_spawn_multiple_with_stdio() {
|
||||
let mut cmd = Command::new("/bin/sh");
|
||||
cmd.arg("-c")
|
||||
.arg("echo foo; echo bar 1>&2")
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped());
|
||||
|
||||
future::block_on(async move {
|
||||
let p1 = cmd.spawn().unwrap();
|
||||
let out1 = p1.output().await.unwrap();
|
||||
assert_eq!(out1.stdout, b"foo\n");
|
||||
assert_eq!(out1.stderr, b"bar\n");
|
||||
|
||||
let p2 = cmd.spawn().unwrap();
|
||||
let out2 = p2.output().await.unwrap();
|
||||
assert_eq!(out2.stdout, b"foo\n");
|
||||
assert_eq!(out2.stderr, b"bar\n");
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue