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