@@ -20,7 +20,7 @@ use fmt;
20
20
use io;
21
21
use path:: Path ;
22
22
use str;
23
- use sys:: pipe:: { self , AnonPipe } ;
23
+ use sys:: pipe:: AnonPipe ;
24
24
use sys:: process as imp;
25
25
use sys_common:: { AsInner , AsInnerMut , FromInner , IntoInner } ;
26
26
use thread:: { self , JoinHandle } ;
@@ -77,6 +77,17 @@ impl AsInner<imp::Process> for Child {
77
77
fn as_inner ( & self ) -> & imp:: Process { & self . handle }
78
78
}
79
79
80
+ impl FromInner < ( imp:: Process , imp:: StdioPipes ) > for Child {
81
+ fn from_inner ( ( handle, io) : ( imp:: Process , imp:: StdioPipes ) ) -> Child {
82
+ Child {
83
+ handle : handle,
84
+ stdin : io. stdin . map ( ChildStdin :: from_inner) ,
85
+ stdout : io. stdout . map ( ChildStdout :: from_inner) ,
86
+ stderr : io. stderr . map ( ChildStderr :: from_inner) ,
87
+ }
88
+ }
89
+ }
90
+
80
91
impl IntoInner < imp:: Process > for Child {
81
92
fn into_inner ( self ) -> imp:: Process { self . handle }
82
93
}
@@ -106,6 +117,12 @@ impl IntoInner<AnonPipe> for ChildStdin {
106
117
fn into_inner ( self ) -> AnonPipe { self . inner }
107
118
}
108
119
120
+ impl FromInner < AnonPipe > for ChildStdin {
121
+ fn from_inner ( pipe : AnonPipe ) -> ChildStdin {
122
+ ChildStdin { inner : pipe }
123
+ }
124
+ }
125
+
109
126
/// A handle to a child process's stdout
110
127
#[ stable( feature = "process" , since = "1.0.0" ) ]
111
128
pub struct ChildStdout {
@@ -127,6 +144,12 @@ impl IntoInner<AnonPipe> for ChildStdout {
127
144
fn into_inner ( self ) -> AnonPipe { self . inner }
128
145
}
129
146
147
+ impl FromInner < AnonPipe > for ChildStdout {
148
+ fn from_inner ( pipe : AnonPipe ) -> ChildStdout {
149
+ ChildStdout { inner : pipe }
150
+ }
151
+ }
152
+
130
153
/// A handle to a child process's stderr
131
154
#[ stable( feature = "process" , since = "1.0.0" ) ]
132
155
pub struct ChildStderr {
@@ -148,6 +171,12 @@ impl IntoInner<AnonPipe> for ChildStderr {
148
171
fn into_inner ( self ) -> AnonPipe { self . inner }
149
172
}
150
173
174
+ impl FromInner < AnonPipe > for ChildStderr {
175
+ fn from_inner ( pipe : AnonPipe ) -> ChildStderr {
176
+ ChildStderr { inner : pipe }
177
+ }
178
+ }
179
+
151
180
/// The `Command` type acts as a process builder, providing fine-grained control
152
181
/// over how a new process should be spawned. A default configuration can be
153
182
/// generated using `Command::new(program)`, where `program` gives a path to the
@@ -167,11 +196,6 @@ impl IntoInner<AnonPipe> for ChildStderr {
167
196
#[ stable( feature = "process" , since = "1.0.0" ) ]
168
197
pub struct Command {
169
198
inner : imp:: Command ,
170
-
171
- // Details explained in the builder methods
172
- stdin : Option < Stdio > ,
173
- stdout : Option < Stdio > ,
174
- stderr : Option < Stdio > ,
175
199
}
176
200
177
201
impl Command {
@@ -187,12 +211,7 @@ impl Command {
187
211
/// otherwise configure the process.
188
212
#[ stable( feature = "process" , since = "1.0.0" ) ]
189
213
pub fn new < S : AsRef < OsStr > > ( program : S ) -> Command {
190
- Command {
191
- inner : imp:: Command :: new ( program. as_ref ( ) ) ,
192
- stdin : None ,
193
- stdout : None ,
194
- stderr : None ,
195
- }
214
+ Command { inner : imp:: Command :: new ( program. as_ref ( ) ) }
196
215
}
197
216
198
217
/// Add an argument to pass to the program.
@@ -247,56 +266,30 @@ impl Command {
247
266
/// Configuration for the child process's stdin handle (file descriptor 0).
248
267
#[ stable( feature = "process" , since = "1.0.0" ) ]
249
268
pub fn stdin ( & mut self , cfg : Stdio ) -> & mut Command {
250
- self . stdin = Some ( cfg) ;
269
+ self . inner . stdin ( cfg. 0 ) ;
251
270
self
252
271
}
253
272
254
273
/// Configuration for the child process's stdout handle (file descriptor 1).
255
274
#[ stable( feature = "process" , since = "1.0.0" ) ]
256
275
pub fn stdout ( & mut self , cfg : Stdio ) -> & mut Command {
257
- self . stdout = Some ( cfg) ;
276
+ self . inner . stdout ( cfg. 0 ) ;
258
277
self
259
278
}
260
279
261
280
/// Configuration for the child process's stderr handle (file descriptor 2).
262
281
#[ stable( feature = "process" , since = "1.0.0" ) ]
263
282
pub fn stderr ( & mut self , cfg : Stdio ) -> & mut Command {
264
- self . stderr = Some ( cfg) ;
283
+ self . inner . stderr ( cfg. 0 ) ;
265
284
self
266
285
}
267
286
268
- fn spawn_inner ( & mut self , default_io : StdioImp ) -> io:: Result < Child > {
269
- let default_io = Stdio ( default_io) ;
270
-
271
- // See comment on `setup_io` for what `_drop_later` is.
272
- let ( their_stdin, our_stdin, _drop_later) = try!(
273
- setup_io ( self . stdin . as_ref ( ) . unwrap_or ( & default_io) , true )
274
- ) ;
275
- let ( their_stdout, our_stdout, _drop_later) = try!(
276
- setup_io ( self . stdout . as_ref ( ) . unwrap_or ( & default_io) , false )
277
- ) ;
278
- let ( their_stderr, our_stderr, _drop_later) = try!(
279
- setup_io ( self . stderr . as_ref ( ) . unwrap_or ( & default_io) , false )
280
- ) ;
281
-
282
- match imp:: Process :: spawn ( & mut self . inner , their_stdin, their_stdout,
283
- their_stderr) {
284
- Err ( e) => Err ( e) ,
285
- Ok ( handle) => Ok ( Child {
286
- handle : handle,
287
- stdin : our_stdin. map ( |fd| ChildStdin { inner : fd } ) ,
288
- stdout : our_stdout. map ( |fd| ChildStdout { inner : fd } ) ,
289
- stderr : our_stderr. map ( |fd| ChildStderr { inner : fd } ) ,
290
- } )
291
- }
292
- }
293
-
294
287
/// Executes the command as a child process, returning a handle to it.
295
288
///
296
289
/// By default, stdin, stdout and stderr are inherited from the parent.
297
290
#[ stable( feature = "process" , since = "1.0.0" ) ]
298
291
pub fn spawn ( & mut self ) -> io:: Result < Child > {
299
- self . spawn_inner ( StdioImp :: Inherit )
292
+ self . inner . spawn ( imp :: Stdio :: Inherit ) . map ( Child :: from_inner )
300
293
}
301
294
302
295
/// Executes the command as a child process, waiting for it to finish and
@@ -319,7 +312,8 @@ impl Command {
319
312
/// ```
320
313
#[ stable( feature = "process" , since = "1.0.0" ) ]
321
314
pub fn output ( & mut self ) -> io:: Result < Output > {
322
- self . spawn_inner ( StdioImp :: MakePipe ) . and_then ( |p| p. wait_with_output ( ) )
315
+ self . inner . spawn ( imp:: Stdio :: MakePipe ) . map ( Child :: from_inner)
316
+ . and_then ( |p| p. wait_with_output ( ) )
323
317
}
324
318
325
319
/// Executes a command as a child process, waiting for it to finish and
@@ -362,33 +356,6 @@ impl AsInnerMut<imp::Command> for Command {
362
356
fn as_inner_mut ( & mut self ) -> & mut imp:: Command { & mut self . inner }
363
357
}
364
358
365
- // Takes a `Stdio` configuration (this module) and whether the to-be-owned
366
- // handle will be readable.
367
- //
368
- // Returns a triple of (stdio to spawn with, stdio to store, stdio to drop). The
369
- // stdio to spawn with is passed down to the `sys` module and indicates how the
370
- // stdio stream should be set up. The "stdio to store" is an object which
371
- // should be returned in the `Child` that makes its way out. The "stdio to drop"
372
- // represents the raw value of "stdio to spawn with", but is the owned variant
373
- // for it. This needs to be dropped after the child spawns
374
- fn setup_io ( io : & Stdio , readable : bool )
375
- -> io:: Result < ( imp:: Stdio , Option < AnonPipe > , Option < AnonPipe > ) >
376
- {
377
- Ok ( match io. 0 {
378
- StdioImp :: MakePipe => {
379
- let ( reader, writer) = try!( pipe:: anon_pipe ( ) ) ;
380
- if readable {
381
- ( imp:: Stdio :: Raw ( reader. raw ( ) ) , Some ( writer) , Some ( reader) )
382
- } else {
383
- ( imp:: Stdio :: Raw ( writer. raw ( ) ) , Some ( reader) , Some ( writer) )
384
- }
385
- }
386
- StdioImp :: Raw ( ref owned) => ( imp:: Stdio :: Raw ( owned. raw ( ) ) , None , None ) ,
387
- StdioImp :: Inherit => ( imp:: Stdio :: Inherit , None , None ) ,
388
- StdioImp :: Null => ( imp:: Stdio :: Null , None , None ) ,
389
- } )
390
- }
391
-
392
359
/// The output of a finished process.
393
360
#[ derive( PartialEq , Eq , Clone ) ]
394
361
#[ stable( feature = "process" , since = "1.0.0" ) ]
@@ -432,34 +399,26 @@ impl fmt::Debug for Output {
432
399
433
400
/// Describes what to do with a standard I/O stream for a child process.
434
401
#[ stable( feature = "process" , since = "1.0.0" ) ]
435
- pub struct Stdio ( StdioImp ) ;
436
-
437
- // The internal enum for stdio setup; see below for descriptions.
438
- enum StdioImp {
439
- MakePipe ,
440
- Raw ( imp:: RawStdio ) ,
441
- Inherit ,
442
- Null ,
443
- }
402
+ pub struct Stdio ( imp:: Stdio ) ;
444
403
445
404
impl Stdio {
446
405
/// A new pipe should be arranged to connect the parent and child processes.
447
406
#[ stable( feature = "process" , since = "1.0.0" ) ]
448
- pub fn piped ( ) -> Stdio { Stdio ( StdioImp :: MakePipe ) }
407
+ pub fn piped ( ) -> Stdio { Stdio ( imp :: Stdio :: MakePipe ) }
449
408
450
409
/// The child inherits from the corresponding parent descriptor.
451
410
#[ stable( feature = "process" , since = "1.0.0" ) ]
452
- pub fn inherit ( ) -> Stdio { Stdio ( StdioImp :: Inherit ) }
411
+ pub fn inherit ( ) -> Stdio { Stdio ( imp :: Stdio :: Inherit ) }
453
412
454
413
/// This stream will be ignored. This is the equivalent of attaching the
455
414
/// stream to `/dev/null`
456
415
#[ stable( feature = "process" , since = "1.0.0" ) ]
457
- pub fn null ( ) -> Stdio { Stdio ( StdioImp :: Null ) }
416
+ pub fn null ( ) -> Stdio { Stdio ( imp :: Stdio :: Null ) }
458
417
}
459
418
460
- impl FromInner < imp:: RawStdio > for Stdio {
461
- fn from_inner ( inner : imp:: RawStdio ) -> Stdio {
462
- Stdio ( StdioImp :: Raw ( inner) )
419
+ impl FromInner < imp:: Stdio > for Stdio {
420
+ fn from_inner ( inner : imp:: Stdio ) -> Stdio {
421
+ Stdio ( inner)
463
422
}
464
423
}
465
424
0 commit comments