diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-05-12 11:03:49 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-05-16 11:18:36 -0700 |
| commit | 3dd3450484c1a914d07da2ab522e3bd27ce2a4bb (patch) | |
| tree | 036734c4a002be0f56eb75901802ac32f9a5000d /src/libstd/process.rs | |
| parent | 5e535eae5c4b70879aefc050a5fe0b8137c07eac (diff) | |
| download | rust-3dd3450484c1a914d07da2ab522e3bd27ce2a4bb.tar.gz rust-3dd3450484c1a914d07da2ab522e3bd27ce2a4bb.zip | |
std: Implement lowering and raising for process IO
This commit implements a number of standard traits for the standard library's
process I/O handles. The `FromRaw{Fd,Handle}` traits are now implemented for the
`Stdio` type and the `AsRaw{Fd,Handle}` traits are now implemented for the
`Child{Stdout,Stdin,Stderr}` types. Additionally this implements the
`AsRawHandle` trait for `Child` on Windows.
The stability markers for these implementations mention that they are stable for
1.1 as I will nominate this commit for cherry-picking to beta.
Diffstat (limited to 'src/libstd/process.rs')
| -rw-r--r-- | src/libstd/process.rs | 99 |
1 files changed, 58 insertions, 41 deletions
diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 61398e16ba0..13892476531 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -22,11 +22,8 @@ use io::{self, Error, ErrorKind}; use path; use sync::mpsc::{channel, Receiver}; use sys::pipe::{self, AnonPipe}; -use sys::process::Command as CommandImp; -use sys::process::Process as ProcessImp; -use sys::process::ExitStatus as ExitStatusImp; -use sys::process::Stdio as StdioImp2; -use sys_common::{AsInner, AsInnerMut}; +use sys::process as imp; +use sys_common::{AsInner, AsInnerMut, FromInner}; use thread; /// Representation of a running or exited child process. @@ -52,10 +49,10 @@ use thread; /// ``` #[stable(feature = "process", since = "1.0.0")] pub struct Child { - handle: ProcessImp, + handle: imp::Process, /// None until wait() or wait_with_output() is called. - status: Option<ExitStatusImp>, + status: Option<imp::ExitStatus>, /// The handle for writing to the child's stdin, if it has been captured #[stable(feature = "process", since = "1.0.0")] @@ -70,6 +67,10 @@ pub struct Child { pub stderr: Option<ChildStderr>, } +impl AsInner<imp::Process> for Child { + fn as_inner(&self) -> &imp::Process { &self.handle } +} + /// A handle to a child procesess's stdin #[stable(feature = "process", since = "1.0.0")] pub struct ChildStdin { @@ -87,6 +88,10 @@ impl Write for ChildStdin { } } +impl AsInner<AnonPipe> for ChildStdin { + fn as_inner(&self) -> &AnonPipe { &self.inner } +} + /// A handle to a child procesess's stdout #[stable(feature = "process", since = "1.0.0")] pub struct ChildStdout { @@ -100,6 +105,10 @@ impl Read for ChildStdout { } } +impl AsInner<AnonPipe> for ChildStdout { + fn as_inner(&self) -> &AnonPipe { &self.inner } +} + /// A handle to a child procesess's stderr #[stable(feature = "process", since = "1.0.0")] pub struct ChildStderr { @@ -113,6 +122,10 @@ impl Read for ChildStderr { } } +impl AsInner<AnonPipe> for ChildStderr { + fn as_inner(&self) -> &AnonPipe { &self.inner } +} + /// The `Command` type acts as a process builder, providing fine-grained control /// over how a new process should be spawned. A default configuration can be /// generated using `Command::new(program)`, where `program` gives a path to the @@ -131,12 +144,12 @@ impl Read for ChildStderr { /// ``` #[stable(feature = "process", since = "1.0.0")] pub struct Command { - inner: CommandImp, + inner: imp::Command, // Details explained in the builder methods - stdin: Option<StdioImp>, - stdout: Option<StdioImp>, - stderr: Option<StdioImp>, + stdin: Option<Stdio>, + stdout: Option<Stdio>, + stderr: Option<Stdio>, } impl Command { @@ -153,7 +166,7 @@ impl Command { #[stable(feature = "process", since = "1.0.0")] pub fn new<S: AsRef<OsStr>>(program: S) -> Command { Command { - inner: CommandImp::new(program.as_ref()), + inner: imp::Command::new(program.as_ref()), stdin: None, stdout: None, stderr: None, @@ -210,25 +223,26 @@ impl Command { /// Configuration for the child process's stdin handle (file descriptor 0). #[stable(feature = "process", since = "1.0.0")] pub fn stdin(&mut self, cfg: Stdio) -> &mut Command { - self.stdin = Some(cfg.0); + self.stdin = Some(cfg); self } /// Configuration for the child process's stdout handle (file descriptor 1). #[stable(feature = "process", since = "1.0.0")] pub fn stdout(&mut self, cfg: Stdio) -> &mut Command { - self.stdout = Some(cfg.0); + self.stdout = Some(cfg); self } /// Configuration for the child process's stderr handle (file descriptor 2). #[stable(feature = "process", since = "1.0.0")] pub fn stderr(&mut self, cfg: Stdio) -> &mut Command { - self.stderr = Some(cfg.0); + self.stderr = Some(cfg); self } fn spawn_inner(&self, default_io: StdioImp) -> io::Result<Child> { + let default_io = Stdio(default_io); let (their_stdin, our_stdin) = try!( setup_io(self.stdin.as_ref().unwrap_or(&default_io), true) ); @@ -239,7 +253,8 @@ impl Command { setup_io(self.stderr.as_ref().unwrap_or(&default_io), false) ); - match ProcessImp::spawn(&self.inner, their_stdin, their_stdout, their_stderr) { + match imp::Process::spawn(&self.inner, their_stdin, their_stdout, + their_stderr) { Err(e) => Err(e), Ok(handle) => Ok(Child { handle: handle, @@ -256,7 +271,7 @@ impl Command { /// By default, stdin, stdout and stderr are inherited by the parent. #[stable(feature = "process", since = "1.0.0")] pub fn spawn(&mut self) -> io::Result<Child> { - self.spawn_inner(StdioImp::Inherit) + self.spawn_inner(StdioImp::Raw(imp::Stdio::Inherit)) } /// Executes the command as a child process, waiting for it to finish and @@ -279,7 +294,7 @@ impl Command { /// ``` #[stable(feature = "process", since = "1.0.0")] pub fn output(&mut self) -> io::Result<Output> { - self.spawn_inner(StdioImp::Piped).and_then(|p| p.wait_with_output()) + self.spawn_inner(StdioImp::MakePipe).and_then(|p| p.wait_with_output()) } /// Executes a command as a child process, waiting for it to finish and @@ -318,29 +333,27 @@ impl fmt::Debug for Command { } } -impl AsInner<CommandImp> for Command { - fn as_inner(&self) -> &CommandImp { &self.inner } +impl AsInner<imp::Command> for Command { + fn as_inner(&self) -> &imp::Command { &self.inner } } -impl AsInnerMut<CommandImp> for Command { - fn as_inner_mut(&mut self) -> &mut CommandImp { &mut self.inner } +impl AsInnerMut<imp::Command> for Command { + fn as_inner_mut(&mut self) -> &mut imp::Command { &mut self.inner } } -fn setup_io(io: &StdioImp, readable: bool) - -> io::Result<(StdioImp2, Option<AnonPipe>)> +fn setup_io(io: &Stdio, readable: bool) + -> io::Result<(imp::Stdio, Option<AnonPipe>)> { - use self::StdioImp::*; - Ok(match *io { - Null => (StdioImp2::None, None), - Inherit => (StdioImp2::Inherit, None), - Piped => { + Ok(match io.0 { + StdioImp::MakePipe => { let (reader, writer) = try!(pipe::anon_pipe()); if readable { - (StdioImp2::Piped(reader), Some(writer)) + (imp::Stdio::Piped(reader), Some(writer)) } else { - (StdioImp2::Piped(writer), Some(reader)) + (imp::Stdio::Piped(writer), Some(reader)) } } + StdioImp::Raw(ref raw) => (raw.clone_if_copy(), None), }) } @@ -364,32 +377,36 @@ pub struct Output { pub struct Stdio(StdioImp); // The internal enum for stdio setup; see below for descriptions. -#[derive(Clone)] enum StdioImp { - Piped, - Inherit, - Null, + MakePipe, + Raw(imp::Stdio), } impl Stdio { /// A new pipe should be arranged to connect the parent and child processes. #[stable(feature = "process", since = "1.0.0")] - pub fn piped() -> Stdio { Stdio(StdioImp::Piped) } + pub fn piped() -> Stdio { Stdio(StdioImp::MakePipe) } /// The child inherits from the corresponding parent descriptor. #[stable(feature = "process", since = "1.0.0")] - pub fn inherit() -> Stdio { Stdio(StdioImp::Inherit) } + pub fn inherit() -> Stdio { Stdio(StdioImp::Raw(imp::Stdio::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::Null) } + pub fn null() -> Stdio { Stdio(StdioImp::Raw(imp::Stdio::None)) } +} + +impl FromInner<imp::Stdio> for Stdio { + fn from_inner(inner: imp::Stdio) -> Stdio { + Stdio(StdioImp::Raw(inner)) + } } /// Describes the result of a process after it has terminated. #[derive(PartialEq, Eq, Clone, Copy, Debug)] #[stable(feature = "process", since = "1.0.0")] -pub struct ExitStatus(ExitStatusImp); +pub struct ExitStatus(imp::ExitStatus); impl ExitStatus { /// Was termination successful? Signal termination not considered a success, @@ -410,8 +427,8 @@ impl ExitStatus { } } -impl AsInner<ExitStatusImp> for ExitStatus { - fn as_inner(&self) -> &ExitStatusImp { &self.0 } +impl AsInner<imp::ExitStatus> for ExitStatus { + fn as_inner(&self) -> &imp::ExitStatus { &self.0 } } #[stable(feature = "process", since = "1.0.0")] |
