1010
1111//! Working with processes.
1212
13- #![ unstable ( feature = "process" , reason = "recently added via RFC 579 " ) ]
13+ #![ stable ( feature = "process" , since = "1.0.0 " ) ]
1414#![ allow( non_upper_case_globals) ]
1515
1616use prelude:: v1:: * ;
@@ -48,27 +48,33 @@ use thread;
4848/// let contents = output.stdout;
4949/// assert!(output.status.success());
5050/// ```
51+ #[ stable( feature = "process" , since = "1.0.0" ) ]
5152pub struct Child {
5253 handle : ProcessImp ,
5354
5455 /// None until wait() or wait_with_output() is called.
5556 status : Option < ExitStatusImp > ,
5657
5758 /// The handle for writing to the child's stdin, if it has been captured
59+ #[ stable( feature = "process" , since = "1.0.0" ) ]
5860 pub stdin : Option < ChildStdin > ,
5961
6062 /// The handle for reading from the child's stdout, if it has been captured
63+ #[ stable( feature = "process" , since = "1.0.0" ) ]
6164 pub stdout : Option < ChildStdout > ,
6265
6366 /// The handle for reading from the child's stderr, if it has been captured
67+ #[ stable( feature = "process" , since = "1.0.0" ) ]
6468 pub stderr : Option < ChildStderr > ,
6569}
6670
6771/// A handle to a child procesess's stdin
72+ #[ stable( feature = "process" , since = "1.0.0" ) ]
6873pub struct ChildStdin {
6974 inner : AnonPipe
7075}
7176
77+ #[ stable( feature = "process" , since = "1.0.0" ) ]
7278impl Write for ChildStdin {
7379 fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
7480 self . inner . write ( buf)
@@ -80,21 +86,25 @@ impl Write for ChildStdin {
8086}
8187
8288/// A handle to a child procesess's stdout
89+ #[ stable( feature = "process" , since = "1.0.0" ) ]
8390pub struct ChildStdout {
8491 inner : AnonPipe
8592}
8693
94+ #[ stable( feature = "process" , since = "1.0.0" ) ]
8795impl Read for ChildStdout {
8896 fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
8997 self . inner . read ( buf)
9098 }
9199}
92100
93101/// A handle to a child procesess's stderr
102+ #[ stable( feature = "process" , since = "1.0.0" ) ]
94103pub struct ChildStderr {
95104 inner : AnonPipe
96105}
97106
107+ #[ stable( feature = "process" , since = "1.0.0" ) ]
98108impl Read for ChildStderr {
99109 fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
100110 self . inner . read ( buf)
@@ -108,15 +118,14 @@ impl Read for ChildStderr {
108118/// to be changed (for example, by adding arguments) prior to spawning:
109119///
110120/// ```
111- /// # #![feature(process)]
112- ///
113121/// use std::process::Command;
114122///
115123/// let output = Command::new("sh").arg("-c").arg("echo hello").output().unwrap_or_else(|e| {
116124/// panic!("failed to execute process: {}", e)
117125/// });
118126/// let hello = output.stdout;
119127/// ```
128+ #[ stable( feature = "process" , since = "1.0.0" ) ]
120129pub struct Command {
121130 inner : CommandImp ,
122131
@@ -137,6 +146,7 @@ impl Command {
137146 ///
138147 /// Builder methods are provided to change these defaults and
139148 /// otherwise configure the process.
149+ #[ stable( feature = "process" , since = "1.0.0" ) ]
140150 pub fn new < S : AsOsStr + ?Sized > ( program : & S ) -> Command {
141151 Command {
142152 inner : CommandImp :: new ( program. as_os_str ( ) ) ,
@@ -147,12 +157,14 @@ impl Command {
147157 }
148158
149159 /// Add an argument to pass to the program.
160+ #[ stable( feature = "process" , since = "1.0.0" ) ]
150161 pub fn arg < S : AsOsStr + ?Sized > ( & mut self , arg : & S ) -> & mut Command {
151162 self . inner . arg ( arg. as_os_str ( ) ) ;
152163 self
153164 }
154165
155166 /// Add multiple arguments to pass to the program.
167+ #[ stable( feature = "process" , since = "1.0.0" ) ]
156168 pub fn args < S : AsOsStr > ( & mut self , args : & [ S ] ) -> & mut Command {
157169 self . inner . args ( args. iter ( ) . map ( AsOsStr :: as_os_str) ) ;
158170 self
@@ -162,47 +174,54 @@ impl Command {
162174 ///
163175 /// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
164176 /// and case-sensitive on all other platforms.
165- pub fn env < S : ?Sized , T : ?Sized > ( & mut self , key : & S , val : & T ) -> & mut Command where
166- S : AsOsStr , T : AsOsStr
177+ #[ stable( feature = "process" , since = "1.0.0" ) ]
178+ pub fn env < K : ?Sized , V : ?Sized > ( & mut self , key : & K , val : & V ) -> & mut Command
179+ where K : AsOsStr , V : AsOsStr
167180 {
168181 self . inner . env ( key. as_os_str ( ) , val. as_os_str ( ) ) ;
169182 self
170183 }
171184
172185 /// Removes an environment variable mapping.
173- pub fn env_remove < S : ?Sized + AsOsStr > ( & mut self , key : & S ) -> & mut Command {
186+ #[ stable( feature = "process" , since = "1.0.0" ) ]
187+ pub fn env_remove < K : ?Sized + AsOsStr > ( & mut self , key : & K ) -> & mut Command {
174188 self . inner . env_remove ( key. as_os_str ( ) ) ;
175189 self
176190 }
177191
178192 /// Clears the entire environment map for the child process.
193+ #[ stable( feature = "process" , since = "1.0.0" ) ]
179194 pub fn env_clear ( & mut self ) -> & mut Command {
180195 self . inner . env_clear ( ) ;
181196 self
182197 }
183198
184199 /// Set the working directory for the child process.
200+ #[ stable( feature = "process" , since = "1.0.0" ) ]
185201 pub fn current_dir < P : AsPath + ?Sized > ( & mut self , dir : & P ) -> & mut Command {
186202 self . inner . cwd ( dir. as_path ( ) . as_os_str ( ) ) ;
187203 self
188204 }
189205
190206 /// Configuration for the child process's stdin handle (file descriptor 0).
191207 /// Defaults to `CreatePipe(true, false)` so the input can be written to.
208+ #[ stable( feature = "process" , since = "1.0.0" ) ]
192209 pub fn stdin ( & mut self , cfg : Stdio ) -> & mut Command {
193210 self . stdin = Some ( cfg. 0 ) ;
194211 self
195212 }
196213
197214 /// Configuration for the child process's stdout handle (file descriptor 1).
198215 /// Defaults to `CreatePipe(false, true)` so the output can be collected.
216+ #[ stable( feature = "process" , since = "1.0.0" ) ]
199217 pub fn stdout ( & mut self , cfg : Stdio ) -> & mut Command {
200218 self . stdout = Some ( cfg. 0 ) ;
201219 self
202220 }
203221
204222 /// Configuration for the child process's stderr handle (file descriptor 2).
205223 /// Defaults to `CreatePipe(false, true)` so the output can be collected.
224+ #[ stable( feature = "process" , since = "1.0.0" ) ]
206225 pub fn stderr ( & mut self , cfg : Stdio ) -> & mut Command {
207226 self . stderr = Some ( cfg. 0 ) ;
208227 self
@@ -234,6 +253,7 @@ impl Command {
234253 /// Executes the command as a child process, returning a handle to it.
235254 ///
236255 /// By default, stdin, stdout and stderr are inherited by the parent.
256+ #[ stable( feature = "process" , since = "1.0.0" ) ]
237257 pub fn spawn ( & mut self ) -> io:: Result < Child > {
238258 self . spawn_inner ( StdioImp :: Inherit )
239259 }
@@ -258,8 +278,9 @@ impl Command {
258278 /// println!("stdout: {}", String::from_utf8_lossy(output.stdout.as_slice()));
259279 /// println!("stderr: {}", String::from_utf8_lossy(output.stderr.as_slice()));
260280 /// ```
281+ #[ stable( feature = "process" , since = "1.0.0" ) ]
261282 pub fn output ( & mut self ) -> io:: Result < Output > {
262- self . spawn_inner ( StdioImp :: Capture ) . and_then ( |p| p. wait_with_output ( ) )
283+ self . spawn_inner ( StdioImp :: Piped ) . and_then ( |p| p. wait_with_output ( ) )
263284 }
264285
265286 /// Executes a command as a child process, waiting for it to finish and
@@ -279,6 +300,7 @@ impl Command {
279300 ///
280301 /// println!("process exited with: {}", status);
281302 /// ```
303+ #[ stable( feature = "process" , since = "1.0.0" ) ]
282304 pub fn status ( & mut self ) -> io:: Result < ExitStatus > {
283305 self . spawn ( ) . and_then ( |mut p| p. wait ( ) )
284306 }
@@ -317,7 +339,7 @@ fn setup_io(io: &StdioImp, fd: libc::c_int, readable: bool)
317339 Inherit => {
318340 ( Some ( AnonPipe :: from_fd ( fd) ) , None )
319341 }
320- Capture => {
342+ Piped => {
321343 let ( reader, writer) = try!( unsafe { pipe2:: anon_pipe ( ) } ) ;
322344 if readable {
323345 ( Some ( reader) , Some ( writer) )
@@ -330,45 +352,60 @@ fn setup_io(io: &StdioImp, fd: libc::c_int, readable: bool)
330352
331353/// The output of a finished process.
332354#[ derive( PartialEq , Eq , Clone ) ]
355+ #[ stable( feature = "process" , since = "1.0.0" ) ]
333356pub struct Output {
334357 /// The status (exit code) of the process.
358+ #[ stable( feature = "process" , since = "1.0.0" ) ]
335359 pub status : ExitStatus ,
336360 /// The data that the process wrote to stdout.
361+ #[ stable( feature = "process" , since = "1.0.0" ) ]
337362 pub stdout : Vec < u8 > ,
338363 /// The data that the process wrote to stderr.
364+ #[ stable( feature = "process" , since = "1.0.0" ) ]
339365 pub stderr : Vec < u8 > ,
340366}
341367
342368/// Describes what to do with a standard io stream for a child process.
369+ #[ stable( feature = "process" , since = "1.0.0" ) ]
343370pub struct Stdio ( StdioImp ) ;
344371
345372// The internal enum for stdio setup; see below for descriptions.
346373#[ derive( Clone ) ]
347374enum StdioImp {
348- Capture ,
375+ Piped ,
349376 Inherit ,
350377 Null ,
351378}
352379
353380impl Stdio {
354381 /// A new pipe should be arranged to connect the parent and child processes.
355- pub fn capture ( ) -> Stdio { Stdio ( StdioImp :: Capture ) }
382+ #[ unstable( feature = "process_capture" ) ]
383+ #[ deprecated( since = "1.0.0" , reason = "renamed to `Stdio::piped`" ) ]
384+ pub fn capture ( ) -> Stdio { Stdio :: piped ( ) }
385+
386+ /// A new pipe should be arranged to connect the parent and child processes.
387+ #[ stable( feature = "process" , since = "1.0.0" ) ]
388+ pub fn piped ( ) -> Stdio { Stdio ( StdioImp :: Piped ) }
356389
357390 /// The child inherits from the corresponding parent descriptor.
391+ #[ stable( feature = "process" , since = "1.0.0" ) ]
358392 pub fn inherit ( ) -> Stdio { Stdio ( StdioImp :: Inherit ) }
359393
360394 /// This stream will be ignored. This is the equivalent of attaching the
361395 /// stream to `/dev/null`
396+ #[ stable( feature = "process" , since = "1.0.0" ) ]
362397 pub fn null ( ) -> Stdio { Stdio ( StdioImp :: Null ) }
363398}
364399
365400/// Describes the result of a process after it has terminated.
366401#[ derive( PartialEq , Eq , Clone , Copy , Debug ) ]
402+ #[ stable( feature = "process" , since = "1.0.0" ) ]
367403pub struct ExitStatus ( ExitStatusImp ) ;
368404
369405impl ExitStatus {
370406 /// Was termination successful? Signal termination not considered a success,
371407 /// and success is defined as a zero exit status.
408+ #[ stable( feature = "process" , since = "1.0.0" ) ]
372409 pub fn success ( & self ) -> bool {
373410 self . 0 . success ( )
374411 }
@@ -378,6 +415,7 @@ impl ExitStatus {
378415 /// On Unix, this will return `None` if the process was terminated
379416 /// by a signal; `std::os::unix` provides an extension trait for
380417 /// extracting the signal and other details from the `ExitStatus`.
418+ #[ stable( feature = "process" , since = "1.0.0" ) ]
381419 pub fn code ( & self ) -> Option < i32 > {
382420 self . 0 . code ( )
383421 }
@@ -387,6 +425,7 @@ impl AsInner<ExitStatusImp> for ExitStatus {
387425 fn as_inner ( & self ) -> & ExitStatusImp { & self . 0 }
388426}
389427
428+ #[ stable( feature = "process" , since = "1.0.0" ) ]
390429impl fmt:: Display for ExitStatus {
391430 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
392431 self . 0 . fmt ( f)
@@ -396,6 +435,7 @@ impl fmt::Display for ExitStatus {
396435impl Child {
397436 /// Forces the child to exit. This is equivalent to sending a
398437 /// SIGKILL on unix platforms.
438+ #[ stable( feature = "process" , since = "1.0.0" ) ]
399439 pub fn kill ( & mut self ) -> io:: Result < ( ) > {
400440 #[ cfg( unix) ] fn collect_status ( p : & mut Child ) {
401441 // On Linux (and possibly other unices), a process that has exited will
@@ -436,6 +476,7 @@ impl Child {
436476 /// before waiting. This helps avoid deadlock: it ensures that the
437477 /// child does not block waiting for input from the parent, while
438478 /// the parent waits for the child to exit.
479+ #[ stable( feature = "process" , since = "1.0.0" ) ]
439480 pub fn wait ( & mut self ) -> io:: Result < ExitStatus > {
440481 drop ( self . stdin . take ( ) ) ;
441482 match self . status {
@@ -456,6 +497,7 @@ impl Child {
456497 /// before waiting. This helps avoid deadlock: it ensures that the
457498 /// child does not block waiting for input from the parent, while
458499 /// the parent waits for the child to exit.
500+ #[ stable( feature = "process" , since = "1.0.0" ) ]
459501 pub fn wait_with_output ( mut self ) -> io:: Result < Output > {
460502 drop ( self . stdin . take ( ) ) ;
461503 fn read < T : Read + Send + ' static > ( stream : Option < T > ) -> Receiver < io:: Result < Vec < u8 > > > {
@@ -557,7 +599,7 @@ mod tests {
557599 #[ test]
558600 fn stdout_works ( ) {
559601 let mut cmd = Command :: new ( "echo" ) ;
560- cmd. arg ( "foobar" ) . stdout ( Stdio :: capture ( ) ) ;
602+ cmd. arg ( "foobar" ) . stdout ( Stdio :: piped ( ) ) ;
561603 assert_eq ! ( run_output( cmd) , "foobar\n " ) ;
562604 }
563605
@@ -567,7 +609,7 @@ mod tests {
567609 let mut cmd = Command :: new ( "/bin/sh" ) ;
568610 cmd. arg ( "-c" ) . arg ( "pwd" )
569611 . current_dir ( "/" )
570- . stdout ( Stdio :: capture ( ) ) ;
612+ . stdout ( Stdio :: piped ( ) ) ;
571613 assert_eq ! ( run_output( cmd) , "/\n " ) ;
572614 }
573615
@@ -576,8 +618,8 @@ mod tests {
576618 fn stdin_works ( ) {
577619 let mut p = Command :: new ( "/bin/sh" )
578620 . arg ( "-c" ) . arg ( "read line; echo $line" )
579- . stdin ( Stdio :: capture ( ) )
580- . stdout ( Stdio :: capture ( ) )
621+ . stdin ( Stdio :: piped ( ) )
622+ . stdout ( Stdio :: piped ( ) )
581623 . spawn ( ) . unwrap ( ) ;
582624 p. stdin . as_mut ( ) . unwrap ( ) . write ( "foobar" . as_bytes ( ) ) . unwrap ( ) ;
583625 drop ( p. stdin . take ( ) ) ;
@@ -675,7 +717,7 @@ mod tests {
675717 #[ cfg( not( target_os="android" ) ) ]
676718 #[ test]
677719 fn test_wait_with_output_once ( ) {
678- let prog = Command :: new ( "echo" ) . arg ( "hello" ) . stdout ( Stdio :: capture ( ) )
720+ let prog = Command :: new ( "echo" ) . arg ( "hello" ) . stdout ( Stdio :: piped ( ) )
679721 . spawn ( ) . unwrap ( ) ;
680722 let Output { status, stdout, stderr} = prog. wait_with_output ( ) . unwrap ( ) ;
681723 let output_str = str:: from_utf8 ( stdout. as_slice ( ) ) . unwrap ( ) ;
0 commit comments