From 56a5ff284a0a49558381230d5711cced9cba4605 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 9 Jun 2015 16:41:14 -0700 Subject: std: Tweak process raising/lowering implementations * Slate these features to be stable in 1.2 instead of 1.1 (not being backported) * Have the `FromRawFd` implementations follow the contract of the `FromRawFd` trait by taking ownership of the primitive specified. * Refactor the implementations slightly to remove the `unreachable!` blocks as well as separating the stdio representation of `std::process` from `std::sys::process`. --- src/libstd/process.rs | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) (limited to 'src/libstd/process.rs') diff --git a/src/libstd/process.rs b/src/libstd/process.rs index ee7cf009fc4..d70b9f09903 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -243,13 +243,15 @@ impl Command { fn spawn_inner(&self, default_io: StdioImp) -> io::Result { let default_io = Stdio(default_io); - let (their_stdin, our_stdin) = try!( + + // See comment on `setup_io` for what `_drop_later` is. + let (their_stdin, our_stdin, _drop_later) = try!( setup_io(self.stdin.as_ref().unwrap_or(&default_io), true) ); - let (their_stdout, our_stdout) = try!( + let (their_stdout, our_stdout, _drop_later) = try!( setup_io(self.stdout.as_ref().unwrap_or(&default_io), false) ); - let (their_stderr, our_stderr) = try!( + let (their_stderr, our_stderr, _drop_later) = try!( setup_io(self.stderr.as_ref().unwrap_or(&default_io), false) ); @@ -271,7 +273,7 @@ impl Command { /// 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 { - self.spawn_inner(StdioImp::Raw(imp::Stdio::Inherit)) + self.spawn_inner(StdioImp::Inherit) } /// Executes the command as a child process, waiting for it to finish and @@ -341,19 +343,30 @@ impl AsInnerMut for Command { fn as_inner_mut(&mut self) -> &mut imp::Command { &mut self.inner } } +// Takes a `Stdio` configuration (this module) and whether the to-be-owned +// handle will be readable. +// +// Returns a triple of (stdio to spawn with, stdio to store, stdio to drop). The +// stdio to spawn with is passed down to the `sys` module and indicates how the +// stdio stream should be set up. The "stdio to store" is an object which +// should be returned in the `Child` that makes its way out. The "stdio to drop" +// represents the raw value of "stdio to spawn with", but is the owned variant +// for it. This needs to be dropped after the child spawns fn setup_io(io: &Stdio, readable: bool) - -> io::Result<(imp::Stdio, Option)> + -> io::Result<(imp::Stdio, Option, Option)> { Ok(match io.0 { StdioImp::MakePipe => { let (reader, writer) = try!(pipe::anon_pipe()); if readable { - (imp::Stdio::Piped(reader), Some(writer)) + (imp::Stdio::Raw(reader.raw()), Some(writer), Some(reader)) } else { - (imp::Stdio::Piped(writer), Some(reader)) + (imp::Stdio::Raw(writer.raw()), Some(reader), Some(writer)) } } - StdioImp::Raw(ref raw) => (raw.clone_if_copy(), None), + StdioImp::Raw(ref owned) => (imp::Stdio::Raw(owned.raw()), None, None), + StdioImp::Inherit => (imp::Stdio::Inherit, None, None), + StdioImp::None => (imp::Stdio::None, None, None), }) } @@ -379,7 +392,9 @@ pub struct Stdio(StdioImp); // The internal enum for stdio setup; see below for descriptions. enum StdioImp { MakePipe, - Raw(imp::Stdio), + Raw(imp::RawStdio), + Inherit, + None, } impl Stdio { @@ -389,16 +404,16 @@ impl Stdio { /// The child inherits from the corresponding parent descriptor. #[stable(feature = "process", since = "1.0.0")] - pub fn inherit() -> Stdio { Stdio(StdioImp::Raw(imp::Stdio::Inherit)) } + pub fn inherit() -> Stdio { Stdio(StdioImp::Inherit) } /// This stream will be ignored. This is the equivalent of attaching the /// stream to `/dev/null` #[stable(feature = "process", since = "1.0.0")] - pub fn null() -> Stdio { Stdio(StdioImp::Raw(imp::Stdio::None)) } + pub fn null() -> Stdio { Stdio(StdioImp::None) } } -impl FromInner for Stdio { - fn from_inner(inner: imp::Stdio) -> Stdio { +impl FromInner for Stdio { + fn from_inner(inner: imp::RawStdio) -> Stdio { Stdio(StdioImp::Raw(inner)) } } -- cgit 1.4.1-3-g733a5