]> git.lizzy.rs Git - rust.git/blob - src/libstd/process.rs
233a4d3639c3b807feb3c9ff13c043f0be713c98
[rust.git] / src / libstd / process.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Working with processes.
12
13 #![stable(feature = "process", since = "1.0.0")]
14
15 use io::prelude::*;
16
17 use ffi::OsStr;
18 use fmt;
19 use io;
20 use path::Path;
21 use str;
22 use sys::pipe::{read2, AnonPipe};
23 use sys::process as imp;
24 use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
25
26 /// Representation of a running or exited child process.
27 ///
28 /// This structure is used to represent and manage child processes. A child
29 /// process is created via the [`Command`] struct, which configures the
30 /// spawning process and can itself be constructed using a builder-style
31 /// interface.
32 ///
33 /// # Examples
34 ///
35 /// ```should_panic
36 /// use std::process::Command;
37 ///
38 /// let mut child = Command::new("/bin/cat")
39 ///                         .arg("file.txt")
40 ///                         .spawn()
41 ///                         .expect("failed to execute child");
42 ///
43 /// let ecode = child.wait()
44 ///                  .expect("failed to wait on child");
45 ///
46 /// assert!(ecode.success());
47 /// ```
48 ///
49 /// # Note
50 ///
51 /// Take note that there is no implementation of [`Drop`] for child processes,
52 /// so if you do not ensure the `Child` has exited then it will continue to
53 /// run, even after the `Child` handle to the child process has gone out of
54 /// scope.
55 ///
56 /// Calling [`wait`][`wait`] (or other functions that wrap around it) will make
57 /// the parent process wait until the child has actually exited before
58 /// continuing.
59 ///
60 /// [`Command`]: struct.Command.html
61 /// [`Drop`]: ../../core/ops/trait.Drop.html
62 /// [`wait`]: #method.wait
63 #[stable(feature = "process", since = "1.0.0")]
64 pub struct Child {
65     handle: imp::Process,
66
67     /// The handle for writing to the child's stdin, if it has been captured
68     #[stable(feature = "process", since = "1.0.0")]
69     pub stdin: Option<ChildStdin>,
70
71     /// The handle for reading from the child's stdout, if it has been captured
72     #[stable(feature = "process", since = "1.0.0")]
73     pub stdout: Option<ChildStdout>,
74
75     /// The handle for reading from the child's stderr, if it has been captured
76     #[stable(feature = "process", since = "1.0.0")]
77     pub stderr: Option<ChildStderr>,
78 }
79
80 impl AsInner<imp::Process> for Child {
81     fn as_inner(&self) -> &imp::Process { &self.handle }
82 }
83
84 impl FromInner<(imp::Process, imp::StdioPipes)> for Child {
85     fn from_inner((handle, io): (imp::Process, imp::StdioPipes)) -> Child {
86         Child {
87             handle: handle,
88             stdin: io.stdin.map(ChildStdin::from_inner),
89             stdout: io.stdout.map(ChildStdout::from_inner),
90             stderr: io.stderr.map(ChildStderr::from_inner),
91         }
92     }
93 }
94
95 impl IntoInner<imp::Process> for Child {
96     fn into_inner(self) -> imp::Process { self.handle }
97 }
98
99 /// A handle to a child process's stdin. This struct is used in the [`stdin`]
100 /// field on [`Child`].
101 ///
102 /// [`Child`]: struct.Child.html
103 /// [`stdin`]: struct.Child.html#structfield.stdin
104 #[stable(feature = "process", since = "1.0.0")]
105 pub struct ChildStdin {
106     inner: AnonPipe
107 }
108
109 #[stable(feature = "process", since = "1.0.0")]
110 impl Write for ChildStdin {
111     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
112         self.inner.write(buf)
113     }
114
115     fn flush(&mut self) -> io::Result<()> {
116         Ok(())
117     }
118 }
119
120 impl AsInner<AnonPipe> for ChildStdin {
121     fn as_inner(&self) -> &AnonPipe { &self.inner }
122 }
123
124 impl IntoInner<AnonPipe> for ChildStdin {
125     fn into_inner(self) -> AnonPipe { self.inner }
126 }
127
128 impl FromInner<AnonPipe> for ChildStdin {
129     fn from_inner(pipe: AnonPipe) -> ChildStdin {
130         ChildStdin { inner: pipe }
131     }
132 }
133
134 /// A handle to a child process's stdout. This struct is used in the [`stdout`]
135 /// field on [`Child`].
136 ///
137 /// [`Child`]: struct.Child.html
138 /// [`stdout`]: struct.Child.html#structfield.stdout
139 #[stable(feature = "process", since = "1.0.0")]
140 pub struct ChildStdout {
141     inner: AnonPipe
142 }
143
144 #[stable(feature = "process", since = "1.0.0")]
145 impl Read for ChildStdout {
146     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
147         self.inner.read(buf)
148     }
149     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
150         self.inner.read_to_end(buf)
151     }
152 }
153
154 impl AsInner<AnonPipe> for ChildStdout {
155     fn as_inner(&self) -> &AnonPipe { &self.inner }
156 }
157
158 impl IntoInner<AnonPipe> for ChildStdout {
159     fn into_inner(self) -> AnonPipe { self.inner }
160 }
161
162 impl FromInner<AnonPipe> for ChildStdout {
163     fn from_inner(pipe: AnonPipe) -> ChildStdout {
164         ChildStdout { inner: pipe }
165     }
166 }
167
168 /// A handle to a child process's stderr. This struct is used in the [`stderr`]
169 /// field on [`Child`].
170 ///
171 /// [`Child`]: struct.Child.html
172 /// [`stderr`]: struct.Child.html#structfield.stderr
173 #[stable(feature = "process", since = "1.0.0")]
174 pub struct ChildStderr {
175     inner: AnonPipe
176 }
177
178 #[stable(feature = "process", since = "1.0.0")]
179 impl Read for ChildStderr {
180     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
181         self.inner.read(buf)
182     }
183     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
184         self.inner.read_to_end(buf)
185     }
186 }
187
188 impl AsInner<AnonPipe> for ChildStderr {
189     fn as_inner(&self) -> &AnonPipe { &self.inner }
190 }
191
192 impl IntoInner<AnonPipe> for ChildStderr {
193     fn into_inner(self) -> AnonPipe { self.inner }
194 }
195
196 impl FromInner<AnonPipe> for ChildStderr {
197     fn from_inner(pipe: AnonPipe) -> ChildStderr {
198         ChildStderr { inner: pipe }
199     }
200 }
201
202 /// A process builder, providing fine-grained control
203 /// over how a new process should be spawned.
204 ///
205 /// A default configuration can be
206 /// generated using `Command::new(program)`, where `program` gives a path to the
207 /// program to be executed. Additional builder methods allow the configuration
208 /// to be changed (for example, by adding arguments) prior to spawning:
209 ///
210 /// ```
211 /// use std::process::Command;
212 ///
213 /// let output = Command::new("sh")
214 ///                      .arg("-c")
215 ///                      .arg("echo hello")
216 ///                      .output()
217 ///                      .expect("failed to execute process");
218 ///
219 /// let hello = output.stdout;
220 /// ```
221 #[stable(feature = "process", since = "1.0.0")]
222 pub struct Command {
223     inner: imp::Command,
224 }
225
226 impl Command {
227     /// Constructs a new `Command` for launching the program at
228     /// path `program`, with the following default configuration:
229     ///
230     /// * No arguments to the program
231     /// * Inherit the current process's environment
232     /// * Inherit the current process's working directory
233     /// * Inherit stdin/stdout/stderr for `spawn` or `status`, but create pipes for `output`
234     ///
235     /// Builder methods are provided to change these defaults and
236     /// otherwise configure the process.
237     ///
238     /// # Examples
239     ///
240     /// Basic usage:
241     ///
242     /// ```no_run
243     /// use std::process::Command;
244     ///
245     /// Command::new("sh")
246     ///         .spawn()
247     ///         .expect("sh command failed to start");
248     /// ```
249     #[stable(feature = "process", since = "1.0.0")]
250     pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
251         Command { inner: imp::Command::new(program.as_ref()) }
252     }
253
254     /// Add an argument to pass to the program.
255     ///
256     /// # Examples
257     ///
258     /// Basic usage:
259     ///
260     /// ```no_run
261     /// use std::process::Command;
262     ///
263     /// Command::new("ls")
264     ///         .arg("-l")
265     ///         .arg("-a")
266     ///         .spawn()
267     ///         .expect("ls command failed to start");
268     /// ```
269     #[stable(feature = "process", since = "1.0.0")]
270     pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {
271         self.inner.arg(arg.as_ref());
272         self
273     }
274
275     /// Add multiple arguments to pass to the program.
276     ///
277     /// # Examples
278     ///
279     /// Basic usage:
280     ///
281     /// ```no_run
282     /// use std::process::Command;
283     ///
284     /// Command::new("ls")
285     ///         .args(&["-l", "-a"])
286     ///         .spawn()
287     ///         .expect("ls command failed to start");
288     /// ```
289     #[stable(feature = "process", since = "1.0.0")]
290     pub fn args<S: AsRef<OsStr>>(&mut self, args: &[S]) -> &mut Command {
291         for arg in args {
292             self.arg(arg.as_ref());
293         }
294         self
295     }
296
297     /// Inserts or updates an environment variable mapping.
298     ///
299     /// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
300     /// and case-sensitive on all other platforms.
301     ///
302     /// # Examples
303     ///
304     /// Basic usage:
305     ///
306     /// ```no_run
307     /// use std::process::Command;
308     ///
309     /// Command::new("ls")
310     ///         .env("PATH", "/bin")
311     ///         .spawn()
312     ///         .expect("ls command failed to start");
313     /// ```
314     #[stable(feature = "process", since = "1.0.0")]
315     pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
316         where K: AsRef<OsStr>, V: AsRef<OsStr>
317     {
318         self.inner.env(key.as_ref(), val.as_ref());
319         self
320     }
321
322     /// Removes an environment variable mapping.
323     ///
324     /// # Examples
325     ///
326     /// Basic usage:
327     ///
328     /// ```no_run
329     /// use std::process::Command;
330     ///
331     /// Command::new("ls")
332     ///         .env_remove("PATH")
333     ///         .spawn()
334     ///         .expect("ls command failed to start");
335     /// ```
336     #[stable(feature = "process", since = "1.0.0")]
337     pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
338         self.inner.env_remove(key.as_ref());
339         self
340     }
341
342     /// Clears the entire environment map for the child process.
343     ///
344     /// # Examples
345     ///
346     /// Basic usage:
347     ///
348     /// ```no_run
349     /// use std::process::Command;
350     ///
351     /// Command::new("ls")
352     ///         .env_clear()
353     ///         .spawn()
354     ///         .expect("ls command failed to start");
355     /// ```
356     #[stable(feature = "process", since = "1.0.0")]
357     pub fn env_clear(&mut self) -> &mut Command {
358         self.inner.env_clear();
359         self
360     }
361
362     /// Sets the working directory for the child process.
363     ///
364     /// # Examples
365     ///
366     /// Basic usage:
367     ///
368     /// ```no_run
369     /// use std::process::Command;
370     ///
371     /// Command::new("ls")
372     ///         .current_dir("/bin")
373     ///         .spawn()
374     ///         .expect("ls command failed to start");
375     /// ```
376     #[stable(feature = "process", since = "1.0.0")]
377     pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command {
378         self.inner.cwd(dir.as_ref().as_ref());
379         self
380     }
381
382     /// Configuration for the child process's stdin handle (file descriptor 0).
383     ///
384     /// # Examples
385     ///
386     /// Basic usage:
387     ///
388     /// ```no_run
389     /// use std::process::{Command, Stdio};
390     ///
391     /// Command::new("ls")
392     ///         .stdin(Stdio::null())
393     ///         .spawn()
394     ///         .expect("ls command failed to start");
395     /// ```
396     #[stable(feature = "process", since = "1.0.0")]
397     pub fn stdin(&mut self, cfg: Stdio) -> &mut Command {
398         self.inner.stdin(cfg.0);
399         self
400     }
401
402     /// Configuration for the child process's stdout handle (file descriptor 1).
403     ///
404     /// # Examples
405     ///
406     /// Basic usage:
407     ///
408     /// ```no_run
409     /// use std::process::{Command, Stdio};
410     ///
411     /// Command::new("ls")
412     ///         .stdout(Stdio::null())
413     ///         .spawn()
414     ///         .expect("ls command failed to start");
415     /// ```
416     #[stable(feature = "process", since = "1.0.0")]
417     pub fn stdout(&mut self, cfg: Stdio) -> &mut Command {
418         self.inner.stdout(cfg.0);
419         self
420     }
421
422     /// Configuration for the child process's stderr handle (file descriptor 2).
423     ///
424     /// # Examples
425     ///
426     /// Basic usage:
427     ///
428     /// ```no_run
429     /// use std::process::{Command, Stdio};
430     ///
431     /// Command::new("ls")
432     ///         .stderr(Stdio::null())
433     ///         .spawn()
434     ///         .expect("ls command failed to start");
435     /// ```
436     #[stable(feature = "process", since = "1.0.0")]
437     pub fn stderr(&mut self, cfg: Stdio) -> &mut Command {
438         self.inner.stderr(cfg.0);
439         self
440     }
441
442     /// Executes the command as a child process, returning a handle to it.
443     ///
444     /// By default, stdin, stdout and stderr are inherited from the parent.
445     ///
446     /// # Examples
447     ///
448     /// Basic usage:
449     ///
450     /// ```no_run
451     /// use std::process::Command;
452     ///
453     /// Command::new("ls")
454     ///         .spawn()
455     ///         .expect("ls command failed to start");
456     /// ```
457     #[stable(feature = "process", since = "1.0.0")]
458     pub fn spawn(&mut self) -> io::Result<Child> {
459         self.inner.spawn(imp::Stdio::Inherit, true).map(Child::from_inner)
460     }
461
462     /// Executes the command as a child process, waiting for it to finish and
463     /// collecting all of its output.
464     ///
465     /// By default, stdin, stdout and stderr are captured (and used to
466     /// provide the resulting output).
467     ///
468     /// # Examples
469     ///
470     /// ```should_panic
471     /// use std::process::Command;
472     /// let output = Command::new("/bin/cat")
473     ///                      .arg("file.txt")
474     ///                      .output()
475     ///                      .expect("failed to execute process");
476     ///
477     /// println!("status: {}", output.status);
478     /// println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
479     /// println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
480     ///
481     /// assert!(output.status.success());
482     /// ```
483     #[stable(feature = "process", since = "1.0.0")]
484     pub fn output(&mut self) -> io::Result<Output> {
485         self.inner.spawn(imp::Stdio::MakePipe, false).map(Child::from_inner)
486             .and_then(|p| p.wait_with_output())
487     }
488
489     /// Executes a command as a child process, waiting for it to finish and
490     /// collecting its exit status.
491     ///
492     /// By default, stdin, stdout and stderr are inherited from the parent.
493     ///
494     /// # Examples
495     ///
496     /// ```should_panic
497     /// use std::process::Command;
498     ///
499     /// let status = Command::new("/bin/cat")
500     ///                      .arg("file.txt")
501     ///                      .status()
502     ///                      .expect("failed to execute process");
503     ///
504     /// println!("process exited with: {}", status);
505     ///
506     /// assert!(status.success());
507     /// ```
508     #[stable(feature = "process", since = "1.0.0")]
509     pub fn status(&mut self) -> io::Result<ExitStatus> {
510         self.inner.spawn(imp::Stdio::Inherit, true).map(Child::from_inner)
511                   .and_then(|mut p| p.wait())
512     }
513 }
514
515 #[stable(feature = "rust1", since = "1.0.0")]
516 impl fmt::Debug for Command {
517     /// Format the program and arguments of a Command for display. Any
518     /// non-utf8 data is lossily converted using the utf8 replacement
519     /// character.
520     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
521         self.inner.fmt(f)
522     }
523 }
524
525 impl AsInner<imp::Command> for Command {
526     fn as_inner(&self) -> &imp::Command { &self.inner }
527 }
528
529 impl AsInnerMut<imp::Command> for Command {
530     fn as_inner_mut(&mut self) -> &mut imp::Command { &mut self.inner }
531 }
532
533 /// The output of a finished process.
534 #[derive(PartialEq, Eq, Clone)]
535 #[stable(feature = "process", since = "1.0.0")]
536 pub struct Output {
537     /// The status (exit code) of the process.
538     #[stable(feature = "process", since = "1.0.0")]
539     pub status: ExitStatus,
540     /// The data that the process wrote to stdout.
541     #[stable(feature = "process", since = "1.0.0")]
542     pub stdout: Vec<u8>,
543     /// The data that the process wrote to stderr.
544     #[stable(feature = "process", since = "1.0.0")]
545     pub stderr: Vec<u8>,
546 }
547
548 // If either stderr or stdout are valid utf8 strings it prints the valid
549 // strings, otherwise it prints the byte sequence instead
550 #[stable(feature = "process_output_debug", since = "1.7.0")]
551 impl fmt::Debug for Output {
552     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
553
554         let stdout_utf8 = str::from_utf8(&self.stdout);
555         let stdout_debug: &fmt::Debug = match stdout_utf8 {
556             Ok(ref str) => str,
557             Err(_) => &self.stdout
558         };
559
560         let stderr_utf8 = str::from_utf8(&self.stderr);
561         let stderr_debug: &fmt::Debug = match stderr_utf8 {
562             Ok(ref str) => str,
563             Err(_) => &self.stderr
564         };
565
566         fmt.debug_struct("Output")
567             .field("status", &self.status)
568             .field("stdout", stdout_debug)
569             .field("stderr", stderr_debug)
570             .finish()
571     }
572 }
573
574 /// Describes what to do with a standard I/O stream for a child process.
575 #[stable(feature = "process", since = "1.0.0")]
576 pub struct Stdio(imp::Stdio);
577
578 impl Stdio {
579     /// A new pipe should be arranged to connect the parent and child processes.
580     #[stable(feature = "process", since = "1.0.0")]
581     pub fn piped() -> Stdio { Stdio(imp::Stdio::MakePipe) }
582
583     /// The child inherits from the corresponding parent descriptor.
584     #[stable(feature = "process", since = "1.0.0")]
585     pub fn inherit() -> Stdio { Stdio(imp::Stdio::Inherit) }
586
587     /// This stream will be ignored. This is the equivalent of attaching the
588     /// stream to `/dev/null`
589     #[stable(feature = "process", since = "1.0.0")]
590     pub fn null() -> Stdio { Stdio(imp::Stdio::Null) }
591 }
592
593 impl FromInner<imp::Stdio> for Stdio {
594     fn from_inner(inner: imp::Stdio) -> Stdio {
595         Stdio(inner)
596     }
597 }
598
599 /// Describes the result of a process after it has terminated.
600 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
601 #[stable(feature = "process", since = "1.0.0")]
602 pub struct ExitStatus(imp::ExitStatus);
603
604 impl ExitStatus {
605     /// Was termination successful? Signal termination not considered a success,
606     /// and success is defined as a zero exit status.
607     ///
608     /// # Examples
609     ///
610     /// ```rust,no_run
611     /// use std::process::Command;
612     ///
613     /// let status = Command::new("mkdir")
614     ///                      .arg("projects")
615     ///                      .status()
616     ///                      .expect("failed to execute mkdir");
617     ///
618     /// if status.success() {
619     ///     println!("'projects/' directory created");
620     /// } else {
621     ///     println!("failed to create 'projects/' directory");
622     /// }
623     /// ```
624     #[stable(feature = "process", since = "1.0.0")]
625     pub fn success(&self) -> bool {
626         self.0.success()
627     }
628
629     /// Returns the exit code of the process, if any.
630     ///
631     /// On Unix, this will return `None` if the process was terminated
632     /// by a signal; `std::os::unix` provides an extension trait for
633     /// extracting the signal and other details from the `ExitStatus`.
634     #[stable(feature = "process", since = "1.0.0")]
635     pub fn code(&self) -> Option<i32> {
636         self.0.code()
637     }
638 }
639
640 impl AsInner<imp::ExitStatus> for ExitStatus {
641     fn as_inner(&self) -> &imp::ExitStatus { &self.0 }
642 }
643
644 impl FromInner<imp::ExitStatus> for ExitStatus {
645     fn from_inner(s: imp::ExitStatus) -> ExitStatus {
646         ExitStatus(s)
647     }
648 }
649
650 #[stable(feature = "process", since = "1.0.0")]
651 impl fmt::Display for ExitStatus {
652     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
653         self.0.fmt(f)
654     }
655 }
656
657 impl Child {
658     /// Forces the child to exit. This is equivalent to sending a
659     /// SIGKILL on unix platforms.
660     ///
661     /// # Examples
662     ///
663     /// Basic usage:
664     ///
665     /// ```no_run
666     /// use std::process::Command;
667     ///
668     /// let mut command = Command::new("yes");
669     /// if let Ok(mut child) = command.spawn() {
670     ///     child.kill().expect("command wasn't running");
671     /// } else {
672     ///     println!("yes command didn't start");
673     /// }
674     /// ```
675     #[stable(feature = "process", since = "1.0.0")]
676     pub fn kill(&mut self) -> io::Result<()> {
677         self.handle.kill()
678     }
679
680     /// Returns the OS-assigned process identifier associated with this child.
681     ///
682     /// # Examples
683     ///
684     /// Basic usage:
685     ///
686     /// ```no_run
687     /// use std::process::Command;
688     ///
689     /// let mut command = Command::new("ls");
690     /// if let Ok(child) = command.spawn() {
691     ///     println!("Child's id is {}", child.id());
692     /// } else {
693     ///     println!("ls command didn't start");
694     /// }
695     /// ```
696     #[stable(feature = "process_id", since = "1.3.0")]
697     pub fn id(&self) -> u32 {
698         self.handle.id()
699     }
700
701     /// Waits for the child to exit completely, returning the status that it
702     /// exited with. This function will continue to have the same return value
703     /// after it has been called at least once.
704     ///
705     /// The stdin handle to the child process, if any, will be closed
706     /// before waiting. This helps avoid deadlock: it ensures that the
707     /// child does not block waiting for input from the parent, while
708     /// the parent waits for the child to exit.
709     ///
710     /// # Examples
711     ///
712     /// Basic usage:
713     ///
714     /// ```no_run
715     /// use std::process::Command;
716     ///
717     /// let mut command = Command::new("ls");
718     /// if let Ok(mut child) = command.spawn() {
719     ///     child.wait().expect("command wasn't running");
720     ///     println!("Child has finished its execution!");
721     /// } else {
722     ///     println!("ls command didn't start");
723     /// }
724     /// ```
725     #[stable(feature = "process", since = "1.0.0")]
726     pub fn wait(&mut self) -> io::Result<ExitStatus> {
727         drop(self.stdin.take());
728         self.handle.wait().map(ExitStatus)
729     }
730
731     /// Simultaneously waits for the child to exit and collect all remaining
732     /// output on the stdout/stderr handles, returning an `Output`
733     /// instance.
734     ///
735     /// The stdin handle to the child process, if any, will be closed
736     /// before waiting. This helps avoid deadlock: it ensures that the
737     /// child does not block waiting for input from the parent, while
738     /// the parent waits for the child to exit.
739     ///
740     /// By default, stdin, stdout and stderr are inherited from the parent.
741     /// In order to capture the output into this `Result<Output>` it is
742     /// necessary to create new pipes between parent and child. Use
743     /// `stdout(Stdio::piped())` or `stderr(Stdio::piped())`, respectively.
744     ///
745     /// # Examples
746     ///
747     /// ```should_panic
748     /// use std::process::{Command, Stdio};
749     ///
750     /// let child = Command::new("/bin/cat")
751     ///     .arg("file.txt")
752     ///     .stdout(Stdio::piped())
753     ///     .spawn()
754     ///     .expect("failed to execute child");
755     ///
756     /// let output = child
757     ///     .wait_with_output()
758     ///     .expect("failed to wait on child");
759     ///
760     /// assert!(output.status.success());
761     /// ```
762     ///
763     #[stable(feature = "process", since = "1.0.0")]
764     pub fn wait_with_output(mut self) -> io::Result<Output> {
765         drop(self.stdin.take());
766
767         let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
768         match (self.stdout.take(), self.stderr.take()) {
769             (None, None) => {}
770             (Some(mut out), None) => {
771                 let res = out.read_to_end(&mut stdout);
772                 res.unwrap();
773             }
774             (None, Some(mut err)) => {
775                 let res = err.read_to_end(&mut stderr);
776                 res.unwrap();
777             }
778             (Some(out), Some(err)) => {
779                 let res = read2(out.inner, &mut stdout, err.inner, &mut stderr);
780                 res.unwrap();
781             }
782         }
783
784         let status = self.wait()?;
785         Ok(Output {
786             status: status,
787             stdout: stdout,
788             stderr: stderr,
789         })
790     }
791 }
792
793 /// Terminates the current process with the specified exit code.
794 ///
795 /// This function will never return and will immediately terminate the current
796 /// process. The exit code is passed through to the underlying OS and will be
797 /// available for consumption by another process.
798 ///
799 /// Note that because this function never returns, and that it terminates the
800 /// process, no destructors on the current stack or any other thread's stack
801 /// will be run. If a clean shutdown is needed it is recommended to only call
802 /// this function at a known point where there are no more destructors left
803 /// to run.
804 #[stable(feature = "rust1", since = "1.0.0")]
805 pub fn exit(code: i32) -> ! {
806     ::sys_common::cleanup();
807     ::sys::os::exit(code)
808 }
809
810 #[cfg(test)]
811 mod tests {
812     use io::prelude::*;
813
814     use io::ErrorKind;
815     use str;
816     use super::{Command, Output, Stdio};
817
818     // FIXME(#10380) these tests should not all be ignored on android.
819
820     #[test]
821     #[cfg_attr(target_os = "android", ignore)]
822     #[cfg_attr(target_os = "emscripten", ignore)]
823     fn smoke() {
824         let p = Command::new("true").spawn();
825         assert!(p.is_ok());
826         let mut p = p.unwrap();
827         assert!(p.wait().unwrap().success());
828     }
829
830     #[test]
831     #[cfg_attr(target_os = "android", ignore)]
832     fn smoke_failure() {
833         match Command::new("if-this-is-a-binary-then-the-world-has-ended").spawn() {
834             Ok(..) => panic!(),
835             Err(..) => {}
836         }
837     }
838
839     #[test]
840     #[cfg_attr(target_os = "android", ignore)]
841     #[cfg_attr(target_os = "emscripten", ignore)]
842     fn exit_reported_right() {
843         let p = Command::new("false").spawn();
844         assert!(p.is_ok());
845         let mut p = p.unwrap();
846         assert!(p.wait().unwrap().code() == Some(1));
847         drop(p.wait());
848     }
849
850     #[test]
851     #[cfg(unix)]
852     #[cfg_attr(target_os = "android", ignore)]
853     #[cfg_attr(target_os = "emscripten", ignore)]
854     fn signal_reported_right() {
855         use os::unix::process::ExitStatusExt;
856
857         let mut p = Command::new("/bin/sh")
858                             .arg("-c").arg("read a")
859                             .stdin(Stdio::piped())
860                             .spawn().unwrap();
861         p.kill().unwrap();
862         match p.wait().unwrap().signal() {
863             Some(9) => {},
864             result => panic!("not terminated by signal 9 (instead, {:?})",
865                              result),
866         }
867     }
868
869     pub fn run_output(mut cmd: Command) -> String {
870         let p = cmd.spawn();
871         assert!(p.is_ok());
872         let mut p = p.unwrap();
873         assert!(p.stdout.is_some());
874         let mut ret = String::new();
875         p.stdout.as_mut().unwrap().read_to_string(&mut ret).unwrap();
876         assert!(p.wait().unwrap().success());
877         return ret;
878     }
879
880     #[test]
881     #[cfg_attr(target_os = "android", ignore)]
882     #[cfg_attr(target_os = "emscripten", ignore)]
883     fn stdout_works() {
884         let mut cmd = Command::new("echo");
885         cmd.arg("foobar").stdout(Stdio::piped());
886         assert_eq!(run_output(cmd), "foobar\n");
887     }
888
889     #[test]
890     #[cfg_attr(any(windows, target_os = "android"), ignore)]
891     #[cfg_attr(target_os = "emscripten", ignore)]
892     fn set_current_dir_works() {
893         let mut cmd = Command::new("/bin/sh");
894         cmd.arg("-c").arg("pwd")
895            .current_dir("/")
896            .stdout(Stdio::piped());
897         assert_eq!(run_output(cmd), "/\n");
898     }
899
900     #[test]
901     #[cfg_attr(any(windows, target_os = "android"), ignore)]
902     #[cfg_attr(target_os = "emscripten", ignore)]
903     fn stdin_works() {
904         let mut p = Command::new("/bin/sh")
905                             .arg("-c").arg("read line; echo $line")
906                             .stdin(Stdio::piped())
907                             .stdout(Stdio::piped())
908                             .spawn().unwrap();
909         p.stdin.as_mut().unwrap().write("foobar".as_bytes()).unwrap();
910         drop(p.stdin.take());
911         let mut out = String::new();
912         p.stdout.as_mut().unwrap().read_to_string(&mut out).unwrap();
913         assert!(p.wait().unwrap().success());
914         assert_eq!(out, "foobar\n");
915     }
916
917
918     #[test]
919     #[cfg_attr(target_os = "android", ignore)]
920     #[cfg(unix)]
921     #[cfg_attr(target_os = "emscripten", ignore)]
922     fn uid_works() {
923         use os::unix::prelude::*;
924         use libc;
925         let mut p = Command::new("/bin/sh")
926                             .arg("-c").arg("true")
927                             .uid(unsafe { libc::getuid() })
928                             .gid(unsafe { libc::getgid() })
929                             .spawn().unwrap();
930         assert!(p.wait().unwrap().success());
931     }
932
933     #[test]
934     #[cfg_attr(target_os = "android", ignore)]
935     #[cfg(unix)]
936     fn uid_to_root_fails() {
937         use os::unix::prelude::*;
938         use libc;
939
940         // if we're already root, this isn't a valid test. Most of the bots run
941         // as non-root though (android is an exception).
942         if unsafe { libc::getuid() == 0 } { return }
943         assert!(Command::new("/bin/ls").uid(0).gid(0).spawn().is_err());
944     }
945
946     #[test]
947     #[cfg_attr(target_os = "android", ignore)]
948     #[cfg_attr(target_os = "emscripten", ignore)]
949     fn test_process_status() {
950         let mut status = Command::new("false").status().unwrap();
951         assert!(status.code() == Some(1));
952
953         status = Command::new("true").status().unwrap();
954         assert!(status.success());
955     }
956
957     #[test]
958     #[cfg_attr(target_os = "emscripten", ignore)]
959     fn test_process_output_fail_to_start() {
960         match Command::new("/no-binary-by-this-name-should-exist").output() {
961             Err(e) => assert_eq!(e.kind(), ErrorKind::NotFound),
962             Ok(..) => panic!()
963         }
964     }
965
966     #[test]
967     #[cfg_attr(target_os = "android", ignore)]
968     #[cfg_attr(target_os = "emscripten", ignore)]
969     fn test_process_output_output() {
970         let Output {status, stdout, stderr}
971              = Command::new("echo").arg("hello").output().unwrap();
972         let output_str = str::from_utf8(&stdout).unwrap();
973
974         assert!(status.success());
975         assert_eq!(output_str.trim().to_string(), "hello");
976         assert_eq!(stderr, Vec::new());
977     }
978
979     #[test]
980     #[cfg_attr(target_os = "android", ignore)]
981     #[cfg_attr(target_os = "emscripten", ignore)]
982     fn test_process_output_error() {
983         let Output {status, stdout, stderr}
984              = Command::new("mkdir").arg(".").output().unwrap();
985
986         assert!(status.code() == Some(1));
987         assert_eq!(stdout, Vec::new());
988         assert!(!stderr.is_empty());
989     }
990
991     #[test]
992     #[cfg_attr(target_os = "android", ignore)]
993     #[cfg_attr(target_os = "emscripten", ignore)]
994     fn test_finish_once() {
995         let mut prog = Command::new("false").spawn().unwrap();
996         assert!(prog.wait().unwrap().code() == Some(1));
997     }
998
999     #[test]
1000     #[cfg_attr(target_os = "android", ignore)]
1001     #[cfg_attr(target_os = "emscripten", ignore)]
1002     fn test_finish_twice() {
1003         let mut prog = Command::new("false").spawn().unwrap();
1004         assert!(prog.wait().unwrap().code() == Some(1));
1005         assert!(prog.wait().unwrap().code() == Some(1));
1006     }
1007
1008     #[test]
1009     #[cfg_attr(target_os = "android", ignore)]
1010     #[cfg_attr(target_os = "emscripten", ignore)]
1011     fn test_wait_with_output_once() {
1012         let prog = Command::new("echo").arg("hello").stdout(Stdio::piped())
1013             .spawn().unwrap();
1014         let Output {status, stdout, stderr} = prog.wait_with_output().unwrap();
1015         let output_str = str::from_utf8(&stdout).unwrap();
1016
1017         assert!(status.success());
1018         assert_eq!(output_str.trim().to_string(), "hello");
1019         assert_eq!(stderr, Vec::new());
1020     }
1021
1022     #[cfg(all(unix, not(target_os="android")))]
1023     pub fn env_cmd() -> Command {
1024         Command::new("env")
1025     }
1026     #[cfg(target_os="android")]
1027     pub fn env_cmd() -> Command {
1028         let mut cmd = Command::new("/system/bin/sh");
1029         cmd.arg("-c").arg("set");
1030         cmd
1031     }
1032
1033     #[cfg(windows)]
1034     pub fn env_cmd() -> Command {
1035         let mut cmd = Command::new("cmd");
1036         cmd.arg("/c").arg("set");
1037         cmd
1038     }
1039
1040     #[test]
1041     #[cfg_attr(target_os = "emscripten", ignore)]
1042     fn test_inherit_env() {
1043         use env;
1044
1045         let result = env_cmd().output().unwrap();
1046         let output = String::from_utf8(result.stdout).unwrap();
1047
1048         for (ref k, ref v) in env::vars() {
1049             // don't check android RANDOM variables
1050             if cfg!(target_os = "android") && *k == "RANDOM" {
1051                 continue
1052             }
1053
1054             // Windows has hidden environment variables whose names start with
1055             // equals signs (`=`). Those do not show up in the output of the
1056             // `set` command.
1057             assert!((cfg!(windows) && k.starts_with("=")) ||
1058                     k.starts_with("DYLD") ||
1059                     output.contains(&format!("{}={}", *k, *v)) ||
1060                     output.contains(&format!("{}='{}'", *k, *v)),
1061                     "output doesn't contain `{}={}`\n{}",
1062                     k, v, output);
1063         }
1064     }
1065
1066     #[test]
1067     #[cfg_attr(target_os = "emscripten", ignore)]
1068     fn test_override_env() {
1069         use env;
1070
1071         // In some build environments (such as chrooted Nix builds), `env` can
1072         // only be found in the explicitly-provided PATH env variable, not in
1073         // default places such as /bin or /usr/bin. So we need to pass through
1074         // PATH to our sub-process.
1075         let mut cmd = env_cmd();
1076         cmd.env_clear().env("RUN_TEST_NEW_ENV", "123");
1077         if let Some(p) = env::var_os("PATH") {
1078             cmd.env("PATH", &p);
1079         }
1080         let result = cmd.output().unwrap();
1081         let output = String::from_utf8_lossy(&result.stdout).to_string();
1082
1083         assert!(output.contains("RUN_TEST_NEW_ENV=123"),
1084                 "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
1085     }
1086
1087     #[test]
1088     #[cfg_attr(target_os = "emscripten", ignore)]
1089     fn test_add_to_env() {
1090         let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap();
1091         let output = String::from_utf8_lossy(&result.stdout).to_string();
1092
1093         assert!(output.contains("RUN_TEST_NEW_ENV=123"),
1094                 "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
1095     }
1096
1097     // Regression tests for #30858.
1098     #[test]
1099     fn test_interior_nul_in_progname_is_error() {
1100         match Command::new("has-some-\0\0s-inside").spawn() {
1101             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
1102             Ok(_) => panic!(),
1103         }
1104     }
1105
1106     #[test]
1107     fn test_interior_nul_in_arg_is_error() {
1108         match Command::new("echo").arg("has-some-\0\0s-inside").spawn() {
1109             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
1110             Ok(_) => panic!(),
1111         }
1112     }
1113
1114     #[test]
1115     fn test_interior_nul_in_args_is_error() {
1116         match Command::new("echo").args(&["has-some-\0\0s-inside"]).spawn() {
1117             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
1118             Ok(_) => panic!(),
1119         }
1120     }
1121
1122     #[test]
1123     fn test_interior_nul_in_current_dir_is_error() {
1124         match Command::new("echo").current_dir("has-some-\0\0s-inside").spawn() {
1125             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
1126             Ok(_) => panic!(),
1127         }
1128     }
1129
1130     // Regression tests for #30862.
1131     #[test]
1132     fn test_interior_nul_in_env_key_is_error() {
1133         match env_cmd().env("has-some-\0\0s-inside", "value").spawn() {
1134             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
1135             Ok(_) => panic!(),
1136         }
1137     }
1138
1139     #[test]
1140     fn test_interior_nul_in_env_value_is_error() {
1141         match env_cmd().env("key", "has-some-\0\0s-inside").spawn() {
1142             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
1143             Ok(_) => panic!(),
1144         }
1145     }
1146 }