]> git.lizzy.rs Git - rust.git/blob - library/std/src/process.rs
Auto merge of #75028 - MrModder:master, r=steveklabnik
[rust.git] / library / std / src / process.rs
1 //! A module for working with processes.
2 //!
3 //! This module is mostly concerned with spawning and interacting with child
4 //! processes, but it also provides [`abort`] and [`exit`] for terminating the
5 //! current process.
6 //!
7 //! # Spawning a process
8 //!
9 //! The [`Command`] struct is used to configure and spawn processes:
10 //!
11 //! ```no_run
12 //! use std::process::Command;
13 //!
14 //! let output = Command::new("echo")
15 //!                      .arg("Hello world")
16 //!                      .output()
17 //!                      .expect("Failed to execute command");
18 //!
19 //! assert_eq!(b"Hello world\n", output.stdout.as_slice());
20 //! ```
21 //!
22 //! Several methods on [`Command`], such as [`spawn`] or [`output`], can be used
23 //! to spawn a process. In particular, [`output`] spawns the child process and
24 //! waits until the process terminates, while [`spawn`] will return a [`Child`]
25 //! that represents the spawned child process.
26 //!
27 //! # Handling I/O
28 //!
29 //! The [`stdout`], [`stdin`], and [`stderr`] of a child process can be
30 //! configured by passing an [`Stdio`] to the corresponding method on
31 //! [`Command`]. Once spawned, they can be accessed from the [`Child`]. For
32 //! example, piping output from one command into another command can be done
33 //! like so:
34 //!
35 //! ```no_run
36 //! use std::process::{Command, Stdio};
37 //!
38 //! // stdout must be configured with `Stdio::piped` in order to use
39 //! // `echo_child.stdout`
40 //! let echo_child = Command::new("echo")
41 //!     .arg("Oh no, a tpyo!")
42 //!     .stdout(Stdio::piped())
43 //!     .spawn()
44 //!     .expect("Failed to start echo process");
45 //!
46 //! // Note that `echo_child` is moved here, but we won't be needing
47 //! // `echo_child` anymore
48 //! let echo_out = echo_child.stdout.expect("Failed to open echo stdout");
49 //!
50 //! let mut sed_child = Command::new("sed")
51 //!     .arg("s/tpyo/typo/")
52 //!     .stdin(Stdio::from(echo_out))
53 //!     .stdout(Stdio::piped())
54 //!     .spawn()
55 //!     .expect("Failed to start sed process");
56 //!
57 //! let output = sed_child.wait_with_output().expect("Failed to wait on sed");
58 //! assert_eq!(b"Oh no, a typo!\n", output.stdout.as_slice());
59 //! ```
60 //!
61 //! Note that [`ChildStderr`] and [`ChildStdout`] implement [`Read`] and
62 //! [`ChildStdin`] implements [`Write`]:
63 //!
64 //! ```no_run
65 //! use std::process::{Command, Stdio};
66 //! use std::io::Write;
67 //!
68 //! let mut child = Command::new("/bin/cat")
69 //!     .stdin(Stdio::piped())
70 //!     .stdout(Stdio::piped())
71 //!     .spawn()
72 //!     .expect("failed to execute child");
73 //!
74 //! {
75 //!     // limited borrow of stdin
76 //!     let stdin = child.stdin.as_mut().expect("failed to get stdin");
77 //!     stdin.write_all(b"test").expect("failed to write to stdin");
78 //! }
79 //!
80 //! let output = child
81 //!     .wait_with_output()
82 //!     .expect("failed to wait on child");
83 //!
84 //! assert_eq!(b"test", output.stdout.as_slice());
85 //! ```
86 //!
87 //! [`spawn`]: Command::spawn
88 //! [`output`]: Command::output
89 //!
90 //! [`stdout`]: Command::stdout
91 //! [`stdin`]: Command::stdin
92 //! [`stderr`]: Command::stderr
93 //!
94 //! [`Write`]: io::Write
95 //! [`Read`]: io::Read
96
97 #![stable(feature = "process", since = "1.0.0")]
98
99 use crate::io::prelude::*;
100
101 use crate::ffi::OsStr;
102 use crate::fmt;
103 use crate::fs;
104 use crate::io::{self, Initializer, IoSlice, IoSliceMut};
105 use crate::path::Path;
106 use crate::str;
107 use crate::sys::pipe::{read2, AnonPipe};
108 use crate::sys::process as imp;
109 use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
110
111 /// Representation of a running or exited child process.
112 ///
113 /// This structure is used to represent and manage child processes. A child
114 /// process is created via the [`Command`] struct, which configures the
115 /// spawning process and can itself be constructed using a builder-style
116 /// interface.
117 ///
118 /// There is no implementation of [`Drop`] for child processes,
119 /// so if you do not ensure the `Child` has exited then it will continue to
120 /// run, even after the `Child` handle to the child process has gone out of
121 /// scope.
122 ///
123 /// Calling [`wait`] (or other functions that wrap around it) will make
124 /// the parent process wait until the child has actually exited before
125 /// continuing.
126 ///
127 /// # Warning
128 ///
129 /// On some system, calling [`wait`] or similar is necessary for the OS to
130 /// release resources. A process that terminated but has not been waited on is
131 /// still around as a "zombie". Leaving too many zombies around may exhaust
132 /// global resources (for example process IDs).
133 ///
134 /// The standard library does *not* automatically wait on child processes (not
135 /// even if the `Child` is dropped), it is up to the application developer to do
136 /// so. As a consequence, dropping `Child` handles without waiting on them first
137 /// is not recommended in long-running applications.
138 ///
139 /// # Examples
140 ///
141 /// ```should_panic
142 /// use std::process::Command;
143 ///
144 /// let mut child = Command::new("/bin/cat")
145 ///                         .arg("file.txt")
146 ///                         .spawn()
147 ///                         .expect("failed to execute child");
148 ///
149 /// let ecode = child.wait()
150 ///                  .expect("failed to wait on child");
151 ///
152 /// assert!(ecode.success());
153 /// ```
154 ///
155 /// [`wait`]: Child::wait
156 #[stable(feature = "process", since = "1.0.0")]
157 pub struct Child {
158     handle: imp::Process,
159
160     /// The handle for writing to the child's standard input (stdin), if it has
161     /// been captured. To avoid partially moving
162     /// the `child` and thus blocking yourself from calling
163     /// functions on `child` while using `stdin`,
164     /// you might find it helpful:
165     ///
166     /// ```compile_fail,E0425
167     /// let stdin = child.stdin.take().unwrap();
168     /// ```
169     #[stable(feature = "process", since = "1.0.0")]
170     pub stdin: Option<ChildStdin>,
171
172     /// The handle for reading from the child's standard output (stdout), if it
173     /// has been captured. You might find it helpful to do
174     ///
175     /// ```compile_fail,E0425
176     /// let stdout = child.stdout.take().unwrap();
177     /// ```
178     ///
179     /// to avoid partially moving the `child` and thus blocking yourself from calling
180     /// functions on `child` while using `stdout`.
181     #[stable(feature = "process", since = "1.0.0")]
182     pub stdout: Option<ChildStdout>,
183
184     /// The handle for reading from the child's standard error (stderr), if it
185     /// has been captured. You might find it helpful to do
186     ///
187     /// ```compile_fail,E0425
188     /// let stderr = child.stderr.take().unwrap();
189     /// ```
190     ///
191     /// to avoid partially moving the `child` and thus blocking yourself from calling
192     /// functions on `child` while using `stderr`.
193     #[stable(feature = "process", since = "1.0.0")]
194     pub stderr: Option<ChildStderr>,
195 }
196
197 impl AsInner<imp::Process> for Child {
198     fn as_inner(&self) -> &imp::Process {
199         &self.handle
200     }
201 }
202
203 impl FromInner<(imp::Process, imp::StdioPipes)> for Child {
204     fn from_inner((handle, io): (imp::Process, imp::StdioPipes)) -> Child {
205         Child {
206             handle,
207             stdin: io.stdin.map(ChildStdin::from_inner),
208             stdout: io.stdout.map(ChildStdout::from_inner),
209             stderr: io.stderr.map(ChildStderr::from_inner),
210         }
211     }
212 }
213
214 impl IntoInner<imp::Process> for Child {
215     fn into_inner(self) -> imp::Process {
216         self.handle
217     }
218 }
219
220 #[stable(feature = "std_debug", since = "1.16.0")]
221 impl fmt::Debug for Child {
222     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223         f.debug_struct("Child")
224             .field("stdin", &self.stdin)
225             .field("stdout", &self.stdout)
226             .field("stderr", &self.stderr)
227             .finish()
228     }
229 }
230
231 /// A handle to a child process's standard input (stdin).
232 ///
233 /// This struct is used in the [`stdin`] field on [`Child`].
234 ///
235 /// When an instance of `ChildStdin` is [dropped], the `ChildStdin`'s underlying
236 /// file handle will be closed. If the child process was blocked on input prior
237 /// to being dropped, it will become unblocked after dropping.
238 ///
239 /// [`stdin`]: Child::stdin
240 /// [dropped]: Drop
241 #[stable(feature = "process", since = "1.0.0")]
242 pub struct ChildStdin {
243     inner: AnonPipe,
244 }
245
246 #[stable(feature = "process", since = "1.0.0")]
247 impl Write for ChildStdin {
248     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
249         self.inner.write(buf)
250     }
251
252     fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
253         self.inner.write_vectored(bufs)
254     }
255
256     fn is_write_vectored(&self) -> bool {
257         self.inner.is_write_vectored()
258     }
259
260     fn flush(&mut self) -> io::Result<()> {
261         Ok(())
262     }
263 }
264
265 impl AsInner<AnonPipe> for ChildStdin {
266     fn as_inner(&self) -> &AnonPipe {
267         &self.inner
268     }
269 }
270
271 impl IntoInner<AnonPipe> for ChildStdin {
272     fn into_inner(self) -> AnonPipe {
273         self.inner
274     }
275 }
276
277 impl FromInner<AnonPipe> for ChildStdin {
278     fn from_inner(pipe: AnonPipe) -> ChildStdin {
279         ChildStdin { inner: pipe }
280     }
281 }
282
283 #[stable(feature = "std_debug", since = "1.16.0")]
284 impl fmt::Debug for ChildStdin {
285     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
286         f.pad("ChildStdin { .. }")
287     }
288 }
289
290 /// A handle to a child process's standard output (stdout).
291 ///
292 /// This struct is used in the [`stdout`] field on [`Child`].
293 ///
294 /// When an instance of `ChildStdout` is [dropped], the `ChildStdout`'s
295 /// underlying file handle will be closed.
296 ///
297 /// [`stdout`]: Child::stdout
298 /// [dropped]: Drop
299 #[stable(feature = "process", since = "1.0.0")]
300 pub struct ChildStdout {
301     inner: AnonPipe,
302 }
303
304 #[stable(feature = "process", since = "1.0.0")]
305 impl Read for ChildStdout {
306     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
307         self.inner.read(buf)
308     }
309
310     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
311         self.inner.read_vectored(bufs)
312     }
313
314     #[inline]
315     fn is_read_vectored(&self) -> bool {
316         self.inner.is_read_vectored()
317     }
318
319     #[inline]
320     unsafe fn initializer(&self) -> Initializer {
321         Initializer::nop()
322     }
323 }
324
325 impl AsInner<AnonPipe> for ChildStdout {
326     fn as_inner(&self) -> &AnonPipe {
327         &self.inner
328     }
329 }
330
331 impl IntoInner<AnonPipe> for ChildStdout {
332     fn into_inner(self) -> AnonPipe {
333         self.inner
334     }
335 }
336
337 impl FromInner<AnonPipe> for ChildStdout {
338     fn from_inner(pipe: AnonPipe) -> ChildStdout {
339         ChildStdout { inner: pipe }
340     }
341 }
342
343 #[stable(feature = "std_debug", since = "1.16.0")]
344 impl fmt::Debug for ChildStdout {
345     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
346         f.pad("ChildStdout { .. }")
347     }
348 }
349
350 /// A handle to a child process's stderr.
351 ///
352 /// This struct is used in the [`stderr`] field on [`Child`].
353 ///
354 /// When an instance of `ChildStderr` is [dropped], the `ChildStderr`'s
355 /// underlying file handle will be closed.
356 ///
357 /// [`stderr`]: Child::stderr
358 /// [dropped]: Drop
359 #[stable(feature = "process", since = "1.0.0")]
360 pub struct ChildStderr {
361     inner: AnonPipe,
362 }
363
364 #[stable(feature = "process", since = "1.0.0")]
365 impl Read for ChildStderr {
366     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
367         self.inner.read(buf)
368     }
369
370     fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
371         self.inner.read_vectored(bufs)
372     }
373
374     #[inline]
375     fn is_read_vectored(&self) -> bool {
376         self.inner.is_read_vectored()
377     }
378
379     #[inline]
380     unsafe fn initializer(&self) -> Initializer {
381         Initializer::nop()
382     }
383 }
384
385 impl AsInner<AnonPipe> for ChildStderr {
386     fn as_inner(&self) -> &AnonPipe {
387         &self.inner
388     }
389 }
390
391 impl IntoInner<AnonPipe> for ChildStderr {
392     fn into_inner(self) -> AnonPipe {
393         self.inner
394     }
395 }
396
397 impl FromInner<AnonPipe> for ChildStderr {
398     fn from_inner(pipe: AnonPipe) -> ChildStderr {
399         ChildStderr { inner: pipe }
400     }
401 }
402
403 #[stable(feature = "std_debug", since = "1.16.0")]
404 impl fmt::Debug for ChildStderr {
405     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
406         f.pad("ChildStderr { .. }")
407     }
408 }
409
410 /// A process builder, providing fine-grained control
411 /// over how a new process should be spawned.
412 ///
413 /// A default configuration can be
414 /// generated using `Command::new(program)`, where `program` gives a path to the
415 /// program to be executed. Additional builder methods allow the configuration
416 /// to be changed (for example, by adding arguments) prior to spawning:
417 ///
418 /// ```
419 /// use std::process::Command;
420 ///
421 /// let output = if cfg!(target_os = "windows") {
422 ///     Command::new("cmd")
423 ///             .args(&["/C", "echo hello"])
424 ///             .output()
425 ///             .expect("failed to execute process")
426 /// } else {
427 ///     Command::new("sh")
428 ///             .arg("-c")
429 ///             .arg("echo hello")
430 ///             .output()
431 ///             .expect("failed to execute process")
432 /// };
433 ///
434 /// let hello = output.stdout;
435 /// ```
436 ///
437 /// `Command` can be reused to spawn multiple processes. The builder methods
438 /// change the command without needing to immediately spawn the process.
439 ///
440 /// ```no_run
441 /// use std::process::Command;
442 ///
443 /// let mut echo_hello = Command::new("sh");
444 /// echo_hello.arg("-c")
445 ///           .arg("echo hello");
446 /// let hello_1 = echo_hello.output().expect("failed to execute process");
447 /// let hello_2 = echo_hello.output().expect("failed to execute process");
448 /// ```
449 ///
450 /// Similarly, you can call builder methods after spawning a process and then
451 /// spawn a new process with the modified settings.
452 ///
453 /// ```no_run
454 /// use std::process::Command;
455 ///
456 /// let mut list_dir = Command::new("ls");
457 ///
458 /// // Execute `ls` in the current directory of the program.
459 /// list_dir.status().expect("process failed to execute");
460 ///
461 /// println!();
462 ///
463 /// // Change `ls` to execute in the root directory.
464 /// list_dir.current_dir("/");
465 ///
466 /// // And then execute `ls` again but in the root directory.
467 /// list_dir.status().expect("process failed to execute");
468 /// ```
469 #[stable(feature = "process", since = "1.0.0")]
470 pub struct Command {
471     inner: imp::Command,
472 }
473
474 impl Command {
475     /// Constructs a new `Command` for launching the program at
476     /// path `program`, with the following default configuration:
477     ///
478     /// * No arguments to the program
479     /// * Inherit the current process's environment
480     /// * Inherit the current process's working directory
481     /// * Inherit stdin/stdout/stderr for `spawn` or `status`, but create pipes for `output`
482     ///
483     /// Builder methods are provided to change these defaults and
484     /// otherwise configure the process.
485     ///
486     /// If `program` is not an absolute path, the `PATH` will be searched in
487     /// an OS-defined way.
488     ///
489     /// The search path to be used may be controlled by setting the
490     /// `PATH` environment variable on the Command,
491     /// but this has some implementation limitations on Windows
492     /// (see issue #37519).
493     ///
494     /// # Examples
495     ///
496     /// Basic usage:
497     ///
498     /// ```no_run
499     /// use std::process::Command;
500     ///
501     /// Command::new("sh")
502     ///         .spawn()
503     ///         .expect("sh command failed to start");
504     /// ```
505     #[stable(feature = "process", since = "1.0.0")]
506     pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
507         Command { inner: imp::Command::new(program.as_ref()) }
508     }
509
510     /// Adds an argument to pass to the program.
511     ///
512     /// Only one argument can be passed per use. So instead of:
513     ///
514     /// ```no_run
515     /// # std::process::Command::new("sh")
516     /// .arg("-C /path/to/repo")
517     /// # ;
518     /// ```
519     ///
520     /// usage would be:
521     ///
522     /// ```no_run
523     /// # std::process::Command::new("sh")
524     /// .arg("-C")
525     /// .arg("/path/to/repo")
526     /// # ;
527     /// ```
528     ///
529     /// To pass multiple arguments see [`args`].
530     ///
531     /// [`args`]: Command::args
532     ///
533     /// # Examples
534     ///
535     /// Basic usage:
536     ///
537     /// ```no_run
538     /// use std::process::Command;
539     ///
540     /// Command::new("ls")
541     ///         .arg("-l")
542     ///         .arg("-a")
543     ///         .spawn()
544     ///         .expect("ls command failed to start");
545     /// ```
546     #[stable(feature = "process", since = "1.0.0")]
547     pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {
548         self.inner.arg(arg.as_ref());
549         self
550     }
551
552     /// Adds multiple arguments to pass to the program.
553     ///
554     /// To pass a single argument see [`arg`].
555     ///
556     /// [`arg`]: Command::arg
557     ///
558     /// # Examples
559     ///
560     /// Basic usage:
561     ///
562     /// ```no_run
563     /// use std::process::Command;
564     ///
565     /// Command::new("ls")
566     ///         .args(&["-l", "-a"])
567     ///         .spawn()
568     ///         .expect("ls command failed to start");
569     /// ```
570     #[stable(feature = "process", since = "1.0.0")]
571     pub fn args<I, S>(&mut self, args: I) -> &mut Command
572     where
573         I: IntoIterator<Item = S>,
574         S: AsRef<OsStr>,
575     {
576         for arg in args {
577             self.arg(arg.as_ref());
578         }
579         self
580     }
581
582     /// Inserts or updates an environment variable mapping.
583     ///
584     /// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
585     /// and case-sensitive on all other platforms.
586     ///
587     /// # Examples
588     ///
589     /// Basic usage:
590     ///
591     /// ```no_run
592     /// use std::process::Command;
593     ///
594     /// Command::new("ls")
595     ///         .env("PATH", "/bin")
596     ///         .spawn()
597     ///         .expect("ls command failed to start");
598     /// ```
599     #[stable(feature = "process", since = "1.0.0")]
600     pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
601     where
602         K: AsRef<OsStr>,
603         V: AsRef<OsStr>,
604     {
605         self.inner.env_mut().set(key.as_ref(), val.as_ref());
606         self
607     }
608
609     /// Adds or updates multiple environment variable mappings.
610     ///
611     /// # Examples
612     ///
613     /// Basic usage:
614     ///
615     /// ```no_run
616     /// use std::process::{Command, Stdio};
617     /// use std::env;
618     /// use std::collections::HashMap;
619     ///
620     /// let filtered_env : HashMap<String, String> =
621     ///     env::vars().filter(|&(ref k, _)|
622     ///         k == "TERM" || k == "TZ" || k == "LANG" || k == "PATH"
623     ///     ).collect();
624     ///
625     /// Command::new("printenv")
626     ///         .stdin(Stdio::null())
627     ///         .stdout(Stdio::inherit())
628     ///         .env_clear()
629     ///         .envs(&filtered_env)
630     ///         .spawn()
631     ///         .expect("printenv failed to start");
632     /// ```
633     #[stable(feature = "command_envs", since = "1.19.0")]
634     pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command
635     where
636         I: IntoIterator<Item = (K, V)>,
637         K: AsRef<OsStr>,
638         V: AsRef<OsStr>,
639     {
640         for (ref key, ref val) in vars {
641             self.inner.env_mut().set(key.as_ref(), val.as_ref());
642         }
643         self
644     }
645
646     /// Removes an environment variable mapping.
647     ///
648     /// # Examples
649     ///
650     /// Basic usage:
651     ///
652     /// ```no_run
653     /// use std::process::Command;
654     ///
655     /// Command::new("ls")
656     ///         .env_remove("PATH")
657     ///         .spawn()
658     ///         .expect("ls command failed to start");
659     /// ```
660     #[stable(feature = "process", since = "1.0.0")]
661     pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
662         self.inner.env_mut().remove(key.as_ref());
663         self
664     }
665
666     /// Clears the entire environment map for the child process.
667     ///
668     /// # Examples
669     ///
670     /// Basic usage:
671     ///
672     /// ```no_run
673     /// use std::process::Command;
674     ///
675     /// Command::new("ls")
676     ///         .env_clear()
677     ///         .spawn()
678     ///         .expect("ls command failed to start");
679     /// ```
680     #[stable(feature = "process", since = "1.0.0")]
681     pub fn env_clear(&mut self) -> &mut Command {
682         self.inner.env_mut().clear();
683         self
684     }
685
686     /// Sets the working directory for the child process.
687     ///
688     /// # Platform-specific behavior
689     ///
690     /// If the program path is relative (e.g., `"./script.sh"`), it's ambiguous
691     /// whether it should be interpreted relative to the parent's working
692     /// directory or relative to `current_dir`. The behavior in this case is
693     /// platform specific and unstable, and it's recommended to use
694     /// [`canonicalize`] to get an absolute program path instead.
695     ///
696     /// # Examples
697     ///
698     /// Basic usage:
699     ///
700     /// ```no_run
701     /// use std::process::Command;
702     ///
703     /// Command::new("ls")
704     ///         .current_dir("/bin")
705     ///         .spawn()
706     ///         .expect("ls command failed to start");
707     /// ```
708     ///
709     /// [`canonicalize`]: crate::fs::canonicalize
710     #[stable(feature = "process", since = "1.0.0")]
711     pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command {
712         self.inner.cwd(dir.as_ref().as_ref());
713         self
714     }
715
716     /// Configuration for the child process's standard input (stdin) handle.
717     ///
718     /// Defaults to [`inherit`] when used with `spawn` or `status`, and
719     /// defaults to [`piped`] when used with `output`.
720     ///
721     /// [`inherit`]: Stdio::inherit
722     /// [`piped`]: Stdio::piped
723     ///
724     /// # Examples
725     ///
726     /// Basic usage:
727     ///
728     /// ```no_run
729     /// use std::process::{Command, Stdio};
730     ///
731     /// Command::new("ls")
732     ///         .stdin(Stdio::null())
733     ///         .spawn()
734     ///         .expect("ls command failed to start");
735     /// ```
736     #[stable(feature = "process", since = "1.0.0")]
737     pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
738         self.inner.stdin(cfg.into().0);
739         self
740     }
741
742     /// Configuration for the child process's standard output (stdout) handle.
743     ///
744     /// Defaults to [`inherit`] when used with `spawn` or `status`, and
745     /// defaults to [`piped`] when used with `output`.
746     ///
747     /// [`inherit`]: Stdio::inherit
748     /// [`piped`]: Stdio::piped
749     ///
750     /// # Examples
751     ///
752     /// Basic usage:
753     ///
754     /// ```no_run
755     /// use std::process::{Command, Stdio};
756     ///
757     /// Command::new("ls")
758     ///         .stdout(Stdio::null())
759     ///         .spawn()
760     ///         .expect("ls command failed to start");
761     /// ```
762     #[stable(feature = "process", since = "1.0.0")]
763     pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
764         self.inner.stdout(cfg.into().0);
765         self
766     }
767
768     /// Configuration for the child process's standard error (stderr) handle.
769     ///
770     /// Defaults to [`inherit`] when used with `spawn` or `status`, and
771     /// defaults to [`piped`] when used with `output`.
772     ///
773     /// [`inherit`]: Stdio::inherit
774     /// [`piped`]: Stdio::piped
775     ///
776     /// # Examples
777     ///
778     /// Basic usage:
779     ///
780     /// ```no_run
781     /// use std::process::{Command, Stdio};
782     ///
783     /// Command::new("ls")
784     ///         .stderr(Stdio::null())
785     ///         .spawn()
786     ///         .expect("ls command failed to start");
787     /// ```
788     #[stable(feature = "process", since = "1.0.0")]
789     pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
790         self.inner.stderr(cfg.into().0);
791         self
792     }
793
794     /// Executes the command as a child process, returning a handle to it.
795     ///
796     /// By default, stdin, stdout and stderr are inherited from the parent.
797     ///
798     /// # Examples
799     ///
800     /// Basic usage:
801     ///
802     /// ```no_run
803     /// use std::process::Command;
804     ///
805     /// Command::new("ls")
806     ///         .spawn()
807     ///         .expect("ls command failed to start");
808     /// ```
809     #[stable(feature = "process", since = "1.0.0")]
810     pub fn spawn(&mut self) -> io::Result<Child> {
811         self.inner.spawn(imp::Stdio::Inherit, true).map(Child::from_inner)
812     }
813
814     /// Executes the command as a child process, waiting for it to finish and
815     /// collecting all of its output.
816     ///
817     /// By default, stdout and stderr are captured (and used to provide the
818     /// resulting output). Stdin is not inherited from the parent and any
819     /// attempt by the child process to read from the stdin stream will result
820     /// in the stream immediately closing.
821     ///
822     /// # Examples
823     ///
824     /// ```should_panic
825     /// use std::process::Command;
826     /// use std::io::{self, Write};
827     /// let output = Command::new("/bin/cat")
828     ///                      .arg("file.txt")
829     ///                      .output()
830     ///                      .expect("failed to execute process");
831     ///
832     /// println!("status: {}", output.status);
833     /// io::stdout().write_all(&output.stdout).unwrap();
834     /// io::stderr().write_all(&output.stderr).unwrap();
835     ///
836     /// assert!(output.status.success());
837     /// ```
838     #[stable(feature = "process", since = "1.0.0")]
839     pub fn output(&mut self) -> io::Result<Output> {
840         self.inner
841             .spawn(imp::Stdio::MakePipe, false)
842             .map(Child::from_inner)
843             .and_then(|p| p.wait_with_output())
844     }
845
846     /// Executes a command as a child process, waiting for it to finish and
847     /// collecting its exit status.
848     ///
849     /// By default, stdin, stdout and stderr are inherited from the parent.
850     ///
851     /// # Examples
852     ///
853     /// ```should_panic
854     /// use std::process::Command;
855     ///
856     /// let status = Command::new("/bin/cat")
857     ///                      .arg("file.txt")
858     ///                      .status()
859     ///                      .expect("failed to execute process");
860     ///
861     /// println!("process exited with: {}", status);
862     ///
863     /// assert!(status.success());
864     /// ```
865     #[stable(feature = "process", since = "1.0.0")]
866     pub fn status(&mut self) -> io::Result<ExitStatus> {
867         self.inner
868             .spawn(imp::Stdio::Inherit, true)
869             .map(Child::from_inner)
870             .and_then(|mut p| p.wait())
871     }
872 }
873
874 #[stable(feature = "rust1", since = "1.0.0")]
875 impl fmt::Debug for Command {
876     /// Format the program and arguments of a Command for display. Any
877     /// non-utf8 data is lossily converted using the utf8 replacement
878     /// character.
879     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
880         self.inner.fmt(f)
881     }
882 }
883
884 impl AsInner<imp::Command> for Command {
885     fn as_inner(&self) -> &imp::Command {
886         &self.inner
887     }
888 }
889
890 impl AsInnerMut<imp::Command> for Command {
891     fn as_inner_mut(&mut self) -> &mut imp::Command {
892         &mut self.inner
893     }
894 }
895
896 /// The output of a finished process.
897 ///
898 /// This is returned in a Result by either the [`output`] method of a
899 /// [`Command`], or the [`wait_with_output`] method of a [`Child`]
900 /// process.
901 ///
902 /// [`output`]: Command::output
903 /// [`wait_with_output`]: Child::wait_with_output
904 #[derive(PartialEq, Eq, Clone)]
905 #[stable(feature = "process", since = "1.0.0")]
906 pub struct Output {
907     /// The status (exit code) of the process.
908     #[stable(feature = "process", since = "1.0.0")]
909     pub status: ExitStatus,
910     /// The data that the process wrote to stdout.
911     #[stable(feature = "process", since = "1.0.0")]
912     pub stdout: Vec<u8>,
913     /// The data that the process wrote to stderr.
914     #[stable(feature = "process", since = "1.0.0")]
915     pub stderr: Vec<u8>,
916 }
917
918 // If either stderr or stdout are valid utf8 strings it prints the valid
919 // strings, otherwise it prints the byte sequence instead
920 #[stable(feature = "process_output_debug", since = "1.7.0")]
921 impl fmt::Debug for Output {
922     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
923         let stdout_utf8 = str::from_utf8(&self.stdout);
924         let stdout_debug: &dyn fmt::Debug = match stdout_utf8 {
925             Ok(ref str) => str,
926             Err(_) => &self.stdout,
927         };
928
929         let stderr_utf8 = str::from_utf8(&self.stderr);
930         let stderr_debug: &dyn fmt::Debug = match stderr_utf8 {
931             Ok(ref str) => str,
932             Err(_) => &self.stderr,
933         };
934
935         fmt.debug_struct("Output")
936             .field("status", &self.status)
937             .field("stdout", stdout_debug)
938             .field("stderr", stderr_debug)
939             .finish()
940     }
941 }
942
943 /// Describes what to do with a standard I/O stream for a child process when
944 /// passed to the [`stdin`], [`stdout`], and [`stderr`] methods of [`Command`].
945 ///
946 /// [`stdin`]: Command::stdin
947 /// [`stdout`]: Command::stdout
948 /// [`stderr`]: Command::stderr
949 #[stable(feature = "process", since = "1.0.0")]
950 pub struct Stdio(imp::Stdio);
951
952 impl Stdio {
953     /// A new pipe should be arranged to connect the parent and child processes.
954     ///
955     /// # Examples
956     ///
957     /// With stdout:
958     ///
959     /// ```no_run
960     /// use std::process::{Command, Stdio};
961     ///
962     /// let output = Command::new("echo")
963     ///     .arg("Hello, world!")
964     ///     .stdout(Stdio::piped())
965     ///     .output()
966     ///     .expect("Failed to execute command");
967     ///
968     /// assert_eq!(String::from_utf8_lossy(&output.stdout), "Hello, world!\n");
969     /// // Nothing echoed to console
970     /// ```
971     ///
972     /// With stdin:
973     ///
974     /// ```no_run
975     /// use std::io::Write;
976     /// use std::process::{Command, Stdio};
977     ///
978     /// let mut child = Command::new("rev")
979     ///     .stdin(Stdio::piped())
980     ///     .stdout(Stdio::piped())
981     ///     .spawn()
982     ///     .expect("Failed to spawn child process");
983     ///
984     /// {
985     ///     let stdin = child.stdin.as_mut().expect("Failed to open stdin");
986     ///     stdin.write_all("Hello, world!".as_bytes()).expect("Failed to write to stdin");
987     /// }
988     ///
989     /// let output = child.wait_with_output().expect("Failed to read stdout");
990     /// assert_eq!(String::from_utf8_lossy(&output.stdout), "!dlrow ,olleH");
991     /// ```
992     #[stable(feature = "process", since = "1.0.0")]
993     pub fn piped() -> Stdio {
994         Stdio(imp::Stdio::MakePipe)
995     }
996
997     /// The child inherits from the corresponding parent descriptor.
998     ///
999     /// # Examples
1000     ///
1001     /// With stdout:
1002     ///
1003     /// ```no_run
1004     /// use std::process::{Command, Stdio};
1005     ///
1006     /// let output = Command::new("echo")
1007     ///     .arg("Hello, world!")
1008     ///     .stdout(Stdio::inherit())
1009     ///     .output()
1010     ///     .expect("Failed to execute command");
1011     ///
1012     /// assert_eq!(String::from_utf8_lossy(&output.stdout), "");
1013     /// // "Hello, world!" echoed to console
1014     /// ```
1015     ///
1016     /// With stdin:
1017     ///
1018     /// ```no_run
1019     /// use std::process::{Command, Stdio};
1020     /// use std::io::{self, Write};
1021     ///
1022     /// let output = Command::new("rev")
1023     ///     .stdin(Stdio::inherit())
1024     ///     .stdout(Stdio::piped())
1025     ///     .output()
1026     ///     .expect("Failed to execute command");
1027     ///
1028     /// print!("You piped in the reverse of: ");
1029     /// io::stdout().write_all(&output.stdout).unwrap();
1030     /// ```
1031     #[stable(feature = "process", since = "1.0.0")]
1032     pub fn inherit() -> Stdio {
1033         Stdio(imp::Stdio::Inherit)
1034     }
1035
1036     /// This stream will be ignored. This is the equivalent of attaching the
1037     /// stream to `/dev/null`
1038     ///
1039     /// # Examples
1040     ///
1041     /// With stdout:
1042     ///
1043     /// ```no_run
1044     /// use std::process::{Command, Stdio};
1045     ///
1046     /// let output = Command::new("echo")
1047     ///     .arg("Hello, world!")
1048     ///     .stdout(Stdio::null())
1049     ///     .output()
1050     ///     .expect("Failed to execute command");
1051     ///
1052     /// assert_eq!(String::from_utf8_lossy(&output.stdout), "");
1053     /// // Nothing echoed to console
1054     /// ```
1055     ///
1056     /// With stdin:
1057     ///
1058     /// ```no_run
1059     /// use std::process::{Command, Stdio};
1060     ///
1061     /// let output = Command::new("rev")
1062     ///     .stdin(Stdio::null())
1063     ///     .stdout(Stdio::piped())
1064     ///     .output()
1065     ///     .expect("Failed to execute command");
1066     ///
1067     /// assert_eq!(String::from_utf8_lossy(&output.stdout), "");
1068     /// // Ignores any piped-in input
1069     /// ```
1070     #[stable(feature = "process", since = "1.0.0")]
1071     pub fn null() -> Stdio {
1072         Stdio(imp::Stdio::Null)
1073     }
1074 }
1075
1076 impl FromInner<imp::Stdio> for Stdio {
1077     fn from_inner(inner: imp::Stdio) -> Stdio {
1078         Stdio(inner)
1079     }
1080 }
1081
1082 #[stable(feature = "std_debug", since = "1.16.0")]
1083 impl fmt::Debug for Stdio {
1084     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1085         f.pad("Stdio { .. }")
1086     }
1087 }
1088
1089 #[stable(feature = "stdio_from", since = "1.20.0")]
1090 impl From<ChildStdin> for Stdio {
1091     /// Converts a `ChildStdin` into a `Stdio`
1092     ///
1093     /// # Examples
1094     ///
1095     /// `ChildStdin` will be converted to `Stdio` using `Stdio::from` under the hood.
1096     ///
1097     /// ```rust,no_run
1098     /// use std::process::{Command, Stdio};
1099     ///
1100     /// let reverse = Command::new("rev")
1101     ///     .stdin(Stdio::piped())
1102     ///     .spawn()
1103     ///     .expect("failed reverse command");
1104     ///
1105     /// let _echo = Command::new("echo")
1106     ///     .arg("Hello, world!")
1107     ///     .stdout(reverse.stdin.unwrap()) // Converted into a Stdio here
1108     ///     .output()
1109     ///     .expect("failed echo command");
1110     ///
1111     /// // "!dlrow ,olleH" echoed to console
1112     /// ```
1113     fn from(child: ChildStdin) -> Stdio {
1114         Stdio::from_inner(child.into_inner().into())
1115     }
1116 }
1117
1118 #[stable(feature = "stdio_from", since = "1.20.0")]
1119 impl From<ChildStdout> for Stdio {
1120     /// Converts a `ChildStdout` into a `Stdio`
1121     ///
1122     /// # Examples
1123     ///
1124     /// `ChildStdout` will be converted to `Stdio` using `Stdio::from` under the hood.
1125     ///
1126     /// ```rust,no_run
1127     /// use std::process::{Command, Stdio};
1128     ///
1129     /// let hello = Command::new("echo")
1130     ///     .arg("Hello, world!")
1131     ///     .stdout(Stdio::piped())
1132     ///     .spawn()
1133     ///     .expect("failed echo command");
1134     ///
1135     /// let reverse = Command::new("rev")
1136     ///     .stdin(hello.stdout.unwrap())  // Converted into a Stdio here
1137     ///     .output()
1138     ///     .expect("failed reverse command");
1139     ///
1140     /// assert_eq!(reverse.stdout, b"!dlrow ,olleH\n");
1141     /// ```
1142     fn from(child: ChildStdout) -> Stdio {
1143         Stdio::from_inner(child.into_inner().into())
1144     }
1145 }
1146
1147 #[stable(feature = "stdio_from", since = "1.20.0")]
1148 impl From<ChildStderr> for Stdio {
1149     /// Converts a `ChildStderr` into a `Stdio`
1150     ///
1151     /// # Examples
1152     ///
1153     /// ```rust,no_run
1154     /// use std::process::{Command, Stdio};
1155     ///
1156     /// let reverse = Command::new("rev")
1157     ///     .arg("non_existing_file.txt")
1158     ///     .stderr(Stdio::piped())
1159     ///     .spawn()
1160     ///     .expect("failed reverse command");
1161     ///
1162     /// let cat = Command::new("cat")
1163     ///     .arg("-")
1164     ///     .stdin(reverse.stderr.unwrap()) // Converted into a Stdio here
1165     ///     .output()
1166     ///     .expect("failed echo command");
1167     ///
1168     /// assert_eq!(
1169     ///     String::from_utf8_lossy(&cat.stdout),
1170     ///     "rev: cannot open non_existing_file.txt: No such file or directory\n"
1171     /// );
1172     /// ```
1173     fn from(child: ChildStderr) -> Stdio {
1174         Stdio::from_inner(child.into_inner().into())
1175     }
1176 }
1177
1178 #[stable(feature = "stdio_from", since = "1.20.0")]
1179 impl From<fs::File> for Stdio {
1180     /// Converts a `File` into a `Stdio`
1181     ///
1182     /// # Examples
1183     ///
1184     /// `File` will be converted to `Stdio` using `Stdio::from` under the hood.
1185     ///
1186     /// ```rust,no_run
1187     /// use std::fs::File;
1188     /// use std::process::Command;
1189     ///
1190     /// // With the `foo.txt` file containing `Hello, world!"
1191     /// let file = File::open("foo.txt").unwrap();
1192     ///
1193     /// let reverse = Command::new("rev")
1194     ///     .stdin(file)  // Implicit File conversion into a Stdio
1195     ///     .output()
1196     ///     .expect("failed reverse command");
1197     ///
1198     /// assert_eq!(reverse.stdout, b"!dlrow ,olleH");
1199     /// ```
1200     fn from(file: fs::File) -> Stdio {
1201         Stdio::from_inner(file.into_inner().into())
1202     }
1203 }
1204
1205 /// Describes the result of a process after it has terminated.
1206 ///
1207 /// This `struct` is used to represent the exit status of a child process.
1208 /// Child processes are created via the [`Command`] struct and their exit
1209 /// status is exposed through the [`status`] method, or the [`wait`] method
1210 /// of a [`Child`] process.
1211 ///
1212 /// [`status`]: Command::status
1213 /// [`wait`]: Child::wait
1214 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
1215 #[stable(feature = "process", since = "1.0.0")]
1216 pub struct ExitStatus(imp::ExitStatus);
1217
1218 impl ExitStatus {
1219     /// Was termination successful? Signal termination is not considered a
1220     /// success, and success is defined as a zero exit status.
1221     ///
1222     /// # Examples
1223     ///
1224     /// ```rust,no_run
1225     /// use std::process::Command;
1226     ///
1227     /// let status = Command::new("mkdir")
1228     ///                      .arg("projects")
1229     ///                      .status()
1230     ///                      .expect("failed to execute mkdir");
1231     ///
1232     /// if status.success() {
1233     ///     println!("'projects/' directory created");
1234     /// } else {
1235     ///     println!("failed to create 'projects/' directory");
1236     /// }
1237     /// ```
1238     #[stable(feature = "process", since = "1.0.0")]
1239     pub fn success(&self) -> bool {
1240         self.0.success()
1241     }
1242
1243     /// Returns the exit code of the process, if any.
1244     ///
1245     /// On Unix, this will return `None` if the process was terminated
1246     /// by a signal; `std::os::unix` provides an extension trait for
1247     /// extracting the signal and other details from the `ExitStatus`.
1248     ///
1249     /// # Examples
1250     ///
1251     /// ```no_run
1252     /// use std::process::Command;
1253     ///
1254     /// let status = Command::new("mkdir")
1255     ///                      .arg("projects")
1256     ///                      .status()
1257     ///                      .expect("failed to execute mkdir");
1258     ///
1259     /// match status.code() {
1260     ///     Some(code) => println!("Exited with status code: {}", code),
1261     ///     None       => println!("Process terminated by signal")
1262     /// }
1263     /// ```
1264     #[stable(feature = "process", since = "1.0.0")]
1265     pub fn code(&self) -> Option<i32> {
1266         self.0.code()
1267     }
1268 }
1269
1270 impl AsInner<imp::ExitStatus> for ExitStatus {
1271     fn as_inner(&self) -> &imp::ExitStatus {
1272         &self.0
1273     }
1274 }
1275
1276 impl FromInner<imp::ExitStatus> for ExitStatus {
1277     fn from_inner(s: imp::ExitStatus) -> ExitStatus {
1278         ExitStatus(s)
1279     }
1280 }
1281
1282 #[stable(feature = "process", since = "1.0.0")]
1283 impl fmt::Display for ExitStatus {
1284     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1285         self.0.fmt(f)
1286     }
1287 }
1288
1289 /// This type represents the status code a process can return to its
1290 /// parent under normal termination.
1291 ///
1292 /// Numeric values used in this type don't have portable meanings, and
1293 /// different platforms may mask different amounts of them.
1294 ///
1295 /// For the platform's canonical successful and unsuccessful codes, see
1296 /// the [`SUCCESS`] and [`FAILURE`] associated items.
1297 ///
1298 /// [`SUCCESS`]: ExitCode::SUCCESS
1299 /// [`FAILURE`]: ExitCode::FAILURE
1300 ///
1301 /// **Warning**: While various forms of this were discussed in [RFC #1937],
1302 /// it was ultimately cut from that RFC, and thus this type is more subject
1303 /// to change even than the usual unstable item churn.
1304 ///
1305 /// [RFC #1937]: https://github.com/rust-lang/rfcs/pull/1937
1306 #[derive(Clone, Copy, Debug)]
1307 #[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
1308 pub struct ExitCode(imp::ExitCode);
1309
1310 #[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
1311 impl ExitCode {
1312     /// The canonical ExitCode for successful termination on this platform.
1313     ///
1314     /// Note that a `()`-returning `main` implicitly results in a successful
1315     /// termination, so there's no need to return this from `main` unless
1316     /// you're also returning other possible codes.
1317     #[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
1318     pub const SUCCESS: ExitCode = ExitCode(imp::ExitCode::SUCCESS);
1319
1320     /// The canonical ExitCode for unsuccessful termination on this platform.
1321     ///
1322     /// If you're only returning this and `SUCCESS` from `main`, consider
1323     /// instead returning `Err(_)` and `Ok(())` respectively, which will
1324     /// return the same codes (but will also `eprintln!` the error).
1325     #[unstable(feature = "process_exitcode_placeholder", issue = "48711")]
1326     pub const FAILURE: ExitCode = ExitCode(imp::ExitCode::FAILURE);
1327 }
1328
1329 impl Child {
1330     /// Forces the child process to exit. If the child has already exited, an [`InvalidInput`]
1331     /// error is returned.
1332     ///
1333     /// The mapping to [`ErrorKind`]s is not part of the compatibility contract of the function,
1334     /// especially the [`Other`] kind might change to more specific kinds in the future.
1335     ///
1336     /// This is equivalent to sending a SIGKILL on Unix platforms.
1337     ///
1338     /// # Examples
1339     ///
1340     /// Basic usage:
1341     ///
1342     /// ```no_run
1343     /// use std::process::Command;
1344     ///
1345     /// let mut command = Command::new("yes");
1346     /// if let Ok(mut child) = command.spawn() {
1347     ///     child.kill().expect("command wasn't running");
1348     /// } else {
1349     ///     println!("yes command didn't start");
1350     /// }
1351     /// ```
1352     ///
1353     /// [`ErrorKind`]: io::ErrorKind
1354     /// [`InvalidInput`]: io::ErrorKind::InvalidInput
1355     /// [`Other`]: io::ErrorKind::Other
1356     #[stable(feature = "process", since = "1.0.0")]
1357     pub fn kill(&mut self) -> io::Result<()> {
1358         self.handle.kill()
1359     }
1360
1361     /// Returns the OS-assigned process identifier associated with this child.
1362     ///
1363     /// # Examples
1364     ///
1365     /// Basic usage:
1366     ///
1367     /// ```no_run
1368     /// use std::process::Command;
1369     ///
1370     /// let mut command = Command::new("ls");
1371     /// if let Ok(child) = command.spawn() {
1372     ///     println!("Child's ID is {}", child.id());
1373     /// } else {
1374     ///     println!("ls command didn't start");
1375     /// }
1376     /// ```
1377     #[stable(feature = "process_id", since = "1.3.0")]
1378     pub fn id(&self) -> u32 {
1379         self.handle.id()
1380     }
1381
1382     /// Waits for the child to exit completely, returning the status that it
1383     /// exited with. This function will continue to have the same return value
1384     /// after it has been called at least once.
1385     ///
1386     /// The stdin handle to the child process, if any, will be closed
1387     /// before waiting. This helps avoid deadlock: it ensures that the
1388     /// child does not block waiting for input from the parent, while
1389     /// the parent waits for the child to exit.
1390     ///
1391     /// # Examples
1392     ///
1393     /// Basic usage:
1394     ///
1395     /// ```no_run
1396     /// use std::process::Command;
1397     ///
1398     /// let mut command = Command::new("ls");
1399     /// if let Ok(mut child) = command.spawn() {
1400     ///     child.wait().expect("command wasn't running");
1401     ///     println!("Child has finished its execution!");
1402     /// } else {
1403     ///     println!("ls command didn't start");
1404     /// }
1405     /// ```
1406     #[stable(feature = "process", since = "1.0.0")]
1407     pub fn wait(&mut self) -> io::Result<ExitStatus> {
1408         drop(self.stdin.take());
1409         self.handle.wait().map(ExitStatus)
1410     }
1411
1412     /// Attempts to collect the exit status of the child if it has already
1413     /// exited.
1414     ///
1415     /// This function will not block the calling thread and will only
1416     /// check to see if the child process has exited or not. If the child has
1417     /// exited then on Unix the process ID is reaped. This function is
1418     /// guaranteed to repeatedly return a successful exit status so long as the
1419     /// child has already exited.
1420     ///
1421     /// If the child has exited, then `Ok(Some(status))` is returned. If the
1422     /// exit status is not available at this time then `Ok(None)` is returned.
1423     /// If an error occurs, then that error is returned.
1424     ///
1425     /// Note that unlike `wait`, this function will not attempt to drop stdin.
1426     ///
1427     /// # Examples
1428     ///
1429     /// Basic usage:
1430     ///
1431     /// ```no_run
1432     /// use std::process::Command;
1433     ///
1434     /// let mut child = Command::new("ls").spawn().unwrap();
1435     ///
1436     /// match child.try_wait() {
1437     ///     Ok(Some(status)) => println!("exited with: {}", status),
1438     ///     Ok(None) => {
1439     ///         println!("status not ready yet, let's really wait");
1440     ///         let res = child.wait();
1441     ///         println!("result: {:?}", res);
1442     ///     }
1443     ///     Err(e) => println!("error attempting to wait: {}", e),
1444     /// }
1445     /// ```
1446     #[stable(feature = "process_try_wait", since = "1.18.0")]
1447     pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
1448         Ok(self.handle.try_wait()?.map(ExitStatus))
1449     }
1450
1451     /// Simultaneously waits for the child to exit and collect all remaining
1452     /// output on the stdout/stderr handles, returning an `Output`
1453     /// instance.
1454     ///
1455     /// The stdin handle to the child process, if any, will be closed
1456     /// before waiting. This helps avoid deadlock: it ensures that the
1457     /// child does not block waiting for input from the parent, while
1458     /// the parent waits for the child to exit.
1459     ///
1460     /// By default, stdin, stdout and stderr are inherited from the parent.
1461     /// In order to capture the output into this `Result<Output>` it is
1462     /// necessary to create new pipes between parent and child. Use
1463     /// `stdout(Stdio::piped())` or `stderr(Stdio::piped())`, respectively.
1464     ///
1465     /// # Examples
1466     ///
1467     /// ```should_panic
1468     /// use std::process::{Command, Stdio};
1469     ///
1470     /// let child = Command::new("/bin/cat")
1471     ///     .arg("file.txt")
1472     ///     .stdout(Stdio::piped())
1473     ///     .spawn()
1474     ///     .expect("failed to execute child");
1475     ///
1476     /// let output = child
1477     ///     .wait_with_output()
1478     ///     .expect("failed to wait on child");
1479     ///
1480     /// assert!(output.status.success());
1481     /// ```
1482     ///
1483     #[stable(feature = "process", since = "1.0.0")]
1484     pub fn wait_with_output(mut self) -> io::Result<Output> {
1485         drop(self.stdin.take());
1486
1487         let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
1488         match (self.stdout.take(), self.stderr.take()) {
1489             (None, None) => {}
1490             (Some(mut out), None) => {
1491                 let res = out.read_to_end(&mut stdout);
1492                 res.unwrap();
1493             }
1494             (None, Some(mut err)) => {
1495                 let res = err.read_to_end(&mut stderr);
1496                 res.unwrap();
1497             }
1498             (Some(out), Some(err)) => {
1499                 let res = read2(out.inner, &mut stdout, err.inner, &mut stderr);
1500                 res.unwrap();
1501             }
1502         }
1503
1504         let status = self.wait()?;
1505         Ok(Output { status, stdout, stderr })
1506     }
1507 }
1508
1509 /// Terminates the current process with the specified exit code.
1510 ///
1511 /// This function will never return and will immediately terminate the current
1512 /// process. The exit code is passed through to the underlying OS and will be
1513 /// available for consumption by another process.
1514 ///
1515 /// Note that because this function never returns, and that it terminates the
1516 /// process, no destructors on the current stack or any other thread's stack
1517 /// will be run. If a clean shutdown is needed it is recommended to only call
1518 /// this function at a known point where there are no more destructors left
1519 /// to run.
1520 ///
1521 /// ## Platform-specific behavior
1522 ///
1523 /// **Unix**: On Unix-like platforms, it is unlikely that all 32 bits of `exit`
1524 /// will be visible to a parent process inspecting the exit code. On most
1525 /// Unix-like platforms, only the eight least-significant bits are considered.
1526 ///
1527 /// # Examples
1528 ///
1529 /// Due to this function’s behavior regarding destructors, a conventional way
1530 /// to use the function is to extract the actual computation to another
1531 /// function and compute the exit code from its return value:
1532 ///
1533 /// ```
1534 /// fn run_app() -> Result<(), ()> {
1535 ///     // Application logic here
1536 ///     Ok(())
1537 /// }
1538 ///
1539 /// fn main() {
1540 ///     std::process::exit(match run_app() {
1541 ///         Ok(_) => 0,
1542 ///         Err(err) => {
1543 ///             eprintln!("error: {:?}", err);
1544 ///             1
1545 ///         }
1546 ///     });
1547 /// }
1548 /// ```
1549 ///
1550 /// Due to [platform-specific behavior], the exit code for this example will be
1551 /// `0` on Linux, but `256` on Windows:
1552 ///
1553 /// ```no_run
1554 /// use std::process;
1555 ///
1556 /// process::exit(0x0100);
1557 /// ```
1558 ///
1559 /// [platform-specific behavior]: #platform-specific-behavior
1560 #[stable(feature = "rust1", since = "1.0.0")]
1561 pub fn exit(code: i32) -> ! {
1562     crate::sys_common::cleanup();
1563     crate::sys::os::exit(code)
1564 }
1565
1566 /// Terminates the process in an abnormal fashion.
1567 ///
1568 /// The function will never return and will immediately terminate the current
1569 /// process in a platform specific "abnormal" manner.
1570 ///
1571 /// Note that because this function never returns, and that it terminates the
1572 /// process, no destructors on the current stack or any other thread's stack
1573 /// will be run.
1574 ///
1575 /// This is in contrast to the default behaviour of [`panic!`] which unwinds
1576 /// the current thread's stack and calls all destructors.
1577 /// When `panic="abort"` is set, either as an argument to `rustc` or in a
1578 /// crate's Cargo.toml, [`panic!`] and `abort` are similar. However,
1579 /// [`panic!`] will still call the [panic hook] while `abort` will not.
1580 ///
1581 /// If a clean shutdown is needed it is recommended to only call
1582 /// this function at a known point where there are no more destructors left
1583 /// to run.
1584 ///
1585 /// # Examples
1586 ///
1587 /// ```no_run
1588 /// use std::process;
1589 ///
1590 /// fn main() {
1591 ///     println!("aborting");
1592 ///
1593 ///     process::abort();
1594 ///
1595 ///     // execution never gets here
1596 /// }
1597 /// ```
1598 ///
1599 /// The `abort` function terminates the process, so the destructor will not
1600 /// get run on the example below:
1601 ///
1602 /// ```no_run
1603 /// use std::process;
1604 ///
1605 /// struct HasDrop;
1606 ///
1607 /// impl Drop for HasDrop {
1608 ///     fn drop(&mut self) {
1609 ///         println!("This will never be printed!");
1610 ///     }
1611 /// }
1612 ///
1613 /// fn main() {
1614 ///     let _x = HasDrop;
1615 ///     process::abort();
1616 ///     // the destructor implemented for HasDrop will never get run
1617 /// }
1618 /// ```
1619 ///
1620 /// [panic hook]: crate::panic::set_hook
1621 #[stable(feature = "process_abort", since = "1.17.0")]
1622 pub fn abort() -> ! {
1623     crate::sys::abort_internal();
1624 }
1625
1626 /// Returns the OS-assigned process identifier associated with this process.
1627 ///
1628 /// # Examples
1629 ///
1630 /// Basic usage:
1631 ///
1632 /// ```no_run
1633 /// use std::process;
1634 ///
1635 /// println!("My pid is {}", process::id());
1636 /// ```
1637 ///
1638 ///
1639 #[stable(feature = "getpid", since = "1.26.0")]
1640 pub fn id() -> u32 {
1641     crate::sys::os::getpid()
1642 }
1643
1644 /// A trait for implementing arbitrary return types in the `main` function.
1645 ///
1646 /// The C-main function only supports to return integers as return type.
1647 /// So, every type implementing the `Termination` trait has to be converted
1648 /// to an integer.
1649 ///
1650 /// The default implementations are returning `libc::EXIT_SUCCESS` to indicate
1651 /// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned.
1652 #[cfg_attr(not(test), lang = "termination")]
1653 #[unstable(feature = "termination_trait_lib", issue = "43301")]
1654 #[rustc_on_unimplemented(
1655     message = "`main` has invalid return type `{Self}`",
1656     label = "`main` can only return types that implement `{Termination}`"
1657 )]
1658 pub trait Termination {
1659     /// Is called to get the representation of the value as status code.
1660     /// This status code is returned to the operating system.
1661     fn report(self) -> i32;
1662 }
1663
1664 #[unstable(feature = "termination_trait_lib", issue = "43301")]
1665 impl Termination for () {
1666     #[inline]
1667     fn report(self) -> i32 {
1668         ExitCode::SUCCESS.report()
1669     }
1670 }
1671
1672 #[unstable(feature = "termination_trait_lib", issue = "43301")]
1673 impl<E: fmt::Debug> Termination for Result<(), E> {
1674     fn report(self) -> i32 {
1675         match self {
1676             Ok(()) => ().report(),
1677             Err(err) => Err::<!, _>(err).report(),
1678         }
1679     }
1680 }
1681
1682 #[unstable(feature = "termination_trait_lib", issue = "43301")]
1683 impl Termination for ! {
1684     fn report(self) -> i32 {
1685         self
1686     }
1687 }
1688
1689 #[unstable(feature = "termination_trait_lib", issue = "43301")]
1690 impl<E: fmt::Debug> Termination for Result<!, E> {
1691     fn report(self) -> i32 {
1692         let Err(err) = self;
1693         eprintln!("Error: {:?}", err);
1694         ExitCode::FAILURE.report()
1695     }
1696 }
1697
1698 #[unstable(feature = "termination_trait_lib", issue = "43301")]
1699 impl Termination for ExitCode {
1700     #[inline]
1701     fn report(self) -> i32 {
1702         self.0.as_i32()
1703     }
1704 }
1705
1706 #[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
1707 mod tests {
1708     use crate::io::prelude::*;
1709
1710     use super::{Command, Output, Stdio};
1711     use crate::io::ErrorKind;
1712     use crate::str;
1713
1714     // FIXME(#10380) these tests should not all be ignored on android.
1715
1716     #[test]
1717     #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
1718     fn smoke() {
1719         let p = if cfg!(target_os = "windows") {
1720             Command::new("cmd").args(&["/C", "exit 0"]).spawn()
1721         } else {
1722             Command::new("true").spawn()
1723         };
1724         assert!(p.is_ok());
1725         let mut p = p.unwrap();
1726         assert!(p.wait().unwrap().success());
1727     }
1728
1729     #[test]
1730     #[cfg_attr(target_os = "android", ignore)]
1731     fn smoke_failure() {
1732         match Command::new("if-this-is-a-binary-then-the-world-has-ended").spawn() {
1733             Ok(..) => panic!(),
1734             Err(..) => {}
1735         }
1736     }
1737
1738     #[test]
1739     #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
1740     fn exit_reported_right() {
1741         let p = if cfg!(target_os = "windows") {
1742             Command::new("cmd").args(&["/C", "exit 1"]).spawn()
1743         } else {
1744             Command::new("false").spawn()
1745         };
1746         assert!(p.is_ok());
1747         let mut p = p.unwrap();
1748         assert!(p.wait().unwrap().code() == Some(1));
1749         drop(p.wait());
1750     }
1751
1752     #[test]
1753     #[cfg(unix)]
1754     #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
1755     fn signal_reported_right() {
1756         use crate::os::unix::process::ExitStatusExt;
1757
1758         let mut p =
1759             Command::new("/bin/sh").arg("-c").arg("read a").stdin(Stdio::piped()).spawn().unwrap();
1760         p.kill().unwrap();
1761         match p.wait().unwrap().signal() {
1762             Some(9) => {}
1763             result => panic!("not terminated by signal 9 (instead, {:?})", result),
1764         }
1765     }
1766
1767     pub fn run_output(mut cmd: Command) -> String {
1768         let p = cmd.spawn();
1769         assert!(p.is_ok());
1770         let mut p = p.unwrap();
1771         assert!(p.stdout.is_some());
1772         let mut ret = String::new();
1773         p.stdout.as_mut().unwrap().read_to_string(&mut ret).unwrap();
1774         assert!(p.wait().unwrap().success());
1775         return ret;
1776     }
1777
1778     #[test]
1779     #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
1780     fn stdout_works() {
1781         if cfg!(target_os = "windows") {
1782             let mut cmd = Command::new("cmd");
1783             cmd.args(&["/C", "echo foobar"]).stdout(Stdio::piped());
1784             assert_eq!(run_output(cmd), "foobar\r\n");
1785         } else {
1786             let mut cmd = Command::new("echo");
1787             cmd.arg("foobar").stdout(Stdio::piped());
1788             assert_eq!(run_output(cmd), "foobar\n");
1789         }
1790     }
1791
1792     #[test]
1793     #[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)]
1794     fn set_current_dir_works() {
1795         let mut cmd = Command::new("/bin/sh");
1796         cmd.arg("-c").arg("pwd").current_dir("/").stdout(Stdio::piped());
1797         assert_eq!(run_output(cmd), "/\n");
1798     }
1799
1800     #[test]
1801     #[cfg_attr(any(windows, target_os = "android", target_os = "vxworks"), ignore)]
1802     fn stdin_works() {
1803         let mut p = Command::new("/bin/sh")
1804             .arg("-c")
1805             .arg("read line; echo $line")
1806             .stdin(Stdio::piped())
1807             .stdout(Stdio::piped())
1808             .spawn()
1809             .unwrap();
1810         p.stdin.as_mut().unwrap().write("foobar".as_bytes()).unwrap();
1811         drop(p.stdin.take());
1812         let mut out = String::new();
1813         p.stdout.as_mut().unwrap().read_to_string(&mut out).unwrap();
1814         assert!(p.wait().unwrap().success());
1815         assert_eq!(out, "foobar\n");
1816     }
1817
1818     #[test]
1819     #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
1820     fn test_process_status() {
1821         let mut status = if cfg!(target_os = "windows") {
1822             Command::new("cmd").args(&["/C", "exit 1"]).status().unwrap()
1823         } else {
1824             Command::new("false").status().unwrap()
1825         };
1826         assert!(status.code() == Some(1));
1827
1828         status = if cfg!(target_os = "windows") {
1829             Command::new("cmd").args(&["/C", "exit 0"]).status().unwrap()
1830         } else {
1831             Command::new("true").status().unwrap()
1832         };
1833         assert!(status.success());
1834     }
1835
1836     #[test]
1837     fn test_process_output_fail_to_start() {
1838         match Command::new("/no-binary-by-this-name-should-exist").output() {
1839             Err(e) => assert_eq!(e.kind(), ErrorKind::NotFound),
1840             Ok(..) => panic!(),
1841         }
1842     }
1843
1844     #[test]
1845     #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
1846     fn test_process_output_output() {
1847         let Output { status, stdout, stderr } = if cfg!(target_os = "windows") {
1848             Command::new("cmd").args(&["/C", "echo hello"]).output().unwrap()
1849         } else {
1850             Command::new("echo").arg("hello").output().unwrap()
1851         };
1852         let output_str = str::from_utf8(&stdout).unwrap();
1853
1854         assert!(status.success());
1855         assert_eq!(output_str.trim().to_string(), "hello");
1856         assert_eq!(stderr, Vec::new());
1857     }
1858
1859     #[test]
1860     #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
1861     fn test_process_output_error() {
1862         let Output { status, stdout, stderr } = if cfg!(target_os = "windows") {
1863             Command::new("cmd").args(&["/C", "mkdir ."]).output().unwrap()
1864         } else {
1865             Command::new("mkdir").arg("./").output().unwrap()
1866         };
1867
1868         assert!(status.code() == Some(1));
1869         assert_eq!(stdout, Vec::new());
1870         assert!(!stderr.is_empty());
1871     }
1872
1873     #[test]
1874     #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
1875     fn test_finish_once() {
1876         let mut prog = if cfg!(target_os = "windows") {
1877             Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
1878         } else {
1879             Command::new("false").spawn().unwrap()
1880         };
1881         assert!(prog.wait().unwrap().code() == Some(1));
1882     }
1883
1884     #[test]
1885     #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
1886     fn test_finish_twice() {
1887         let mut prog = if cfg!(target_os = "windows") {
1888             Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
1889         } else {
1890             Command::new("false").spawn().unwrap()
1891         };
1892         assert!(prog.wait().unwrap().code() == Some(1));
1893         assert!(prog.wait().unwrap().code() == Some(1));
1894     }
1895
1896     #[test]
1897     #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)]
1898     fn test_wait_with_output_once() {
1899         let prog = if cfg!(target_os = "windows") {
1900             Command::new("cmd").args(&["/C", "echo hello"]).stdout(Stdio::piped()).spawn().unwrap()
1901         } else {
1902             Command::new("echo").arg("hello").stdout(Stdio::piped()).spawn().unwrap()
1903         };
1904
1905         let Output { status, stdout, stderr } = prog.wait_with_output().unwrap();
1906         let output_str = str::from_utf8(&stdout).unwrap();
1907
1908         assert!(status.success());
1909         assert_eq!(output_str.trim().to_string(), "hello");
1910         assert_eq!(stderr, Vec::new());
1911     }
1912
1913     #[cfg(all(unix, not(target_os = "android")))]
1914     pub fn env_cmd() -> Command {
1915         Command::new("env")
1916     }
1917     #[cfg(target_os = "android")]
1918     pub fn env_cmd() -> Command {
1919         let mut cmd = Command::new("/system/bin/sh");
1920         cmd.arg("-c").arg("set");
1921         cmd
1922     }
1923
1924     #[cfg(windows)]
1925     pub fn env_cmd() -> Command {
1926         let mut cmd = Command::new("cmd");
1927         cmd.arg("/c").arg("set");
1928         cmd
1929     }
1930
1931     #[test]
1932     #[cfg_attr(target_os = "vxworks", ignore)]
1933     fn test_override_env() {
1934         use crate::env;
1935
1936         // In some build environments (such as chrooted Nix builds), `env` can
1937         // only be found in the explicitly-provided PATH env variable, not in
1938         // default places such as /bin or /usr/bin. So we need to pass through
1939         // PATH to our sub-process.
1940         let mut cmd = env_cmd();
1941         cmd.env_clear().env("RUN_TEST_NEW_ENV", "123");
1942         if let Some(p) = env::var_os("PATH") {
1943             cmd.env("PATH", &p);
1944         }
1945         let result = cmd.output().unwrap();
1946         let output = String::from_utf8_lossy(&result.stdout).to_string();
1947
1948         assert!(
1949             output.contains("RUN_TEST_NEW_ENV=123"),
1950             "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}",
1951             output
1952         );
1953     }
1954
1955     #[test]
1956     #[cfg_attr(target_os = "vxworks", ignore)]
1957     fn test_add_to_env() {
1958         let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap();
1959         let output = String::from_utf8_lossy(&result.stdout).to_string();
1960
1961         assert!(
1962             output.contains("RUN_TEST_NEW_ENV=123"),
1963             "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}",
1964             output
1965         );
1966     }
1967
1968     #[test]
1969     #[cfg_attr(target_os = "vxworks", ignore)]
1970     fn test_capture_env_at_spawn() {
1971         use crate::env;
1972
1973         let mut cmd = env_cmd();
1974         cmd.env("RUN_TEST_NEW_ENV1", "123");
1975
1976         // This variable will not be present if the environment has already
1977         // been captured above.
1978         env::set_var("RUN_TEST_NEW_ENV2", "456");
1979         let result = cmd.output().unwrap();
1980         env::remove_var("RUN_TEST_NEW_ENV2");
1981
1982         let output = String::from_utf8_lossy(&result.stdout).to_string();
1983
1984         assert!(
1985             output.contains("RUN_TEST_NEW_ENV1=123"),
1986             "didn't find RUN_TEST_NEW_ENV1 inside of:\n\n{}",
1987             output
1988         );
1989         assert!(
1990             output.contains("RUN_TEST_NEW_ENV2=456"),
1991             "didn't find RUN_TEST_NEW_ENV2 inside of:\n\n{}",
1992             output
1993         );
1994     }
1995
1996     // Regression tests for #30858.
1997     #[test]
1998     fn test_interior_nul_in_progname_is_error() {
1999         match Command::new("has-some-\0\0s-inside").spawn() {
2000             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
2001             Ok(_) => panic!(),
2002         }
2003     }
2004
2005     #[test]
2006     fn test_interior_nul_in_arg_is_error() {
2007         match Command::new("echo").arg("has-some-\0\0s-inside").spawn() {
2008             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
2009             Ok(_) => panic!(),
2010         }
2011     }
2012
2013     #[test]
2014     fn test_interior_nul_in_args_is_error() {
2015         match Command::new("echo").args(&["has-some-\0\0s-inside"]).spawn() {
2016             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
2017             Ok(_) => panic!(),
2018         }
2019     }
2020
2021     #[test]
2022     fn test_interior_nul_in_current_dir_is_error() {
2023         match Command::new("echo").current_dir("has-some-\0\0s-inside").spawn() {
2024             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
2025             Ok(_) => panic!(),
2026         }
2027     }
2028
2029     // Regression tests for #30862.
2030     #[test]
2031     #[cfg_attr(target_os = "vxworks", ignore)]
2032     fn test_interior_nul_in_env_key_is_error() {
2033         match env_cmd().env("has-some-\0\0s-inside", "value").spawn() {
2034             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
2035             Ok(_) => panic!(),
2036         }
2037     }
2038
2039     #[test]
2040     #[cfg_attr(target_os = "vxworks", ignore)]
2041     fn test_interior_nul_in_env_value_is_error() {
2042         match env_cmd().env("key", "has-some-\0\0s-inside").spawn() {
2043             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
2044             Ok(_) => panic!(),
2045         }
2046     }
2047
2048     /// Tests that process creation flags work by debugging a process.
2049     /// Other creation flags make it hard or impossible to detect
2050     /// behavioral changes in the process.
2051     #[test]
2052     #[cfg(windows)]
2053     fn test_creation_flags() {
2054         use crate::os::windows::process::CommandExt;
2055         use crate::sys::c::{BOOL, DWORD, INFINITE};
2056         #[repr(C, packed)]
2057         struct DEBUG_EVENT {
2058             pub event_code: DWORD,
2059             pub process_id: DWORD,
2060             pub thread_id: DWORD,
2061             // This is a union in the real struct, but we don't
2062             // need this data for the purposes of this test.
2063             pub _junk: [u8; 164],
2064         }
2065
2066         extern "system" {
2067             fn WaitForDebugEvent(lpDebugEvent: *mut DEBUG_EVENT, dwMilliseconds: DWORD) -> BOOL;
2068             fn ContinueDebugEvent(
2069                 dwProcessId: DWORD,
2070                 dwThreadId: DWORD,
2071                 dwContinueStatus: DWORD,
2072             ) -> BOOL;
2073         }
2074
2075         const DEBUG_PROCESS: DWORD = 1;
2076         const EXIT_PROCESS_DEBUG_EVENT: DWORD = 5;
2077         const DBG_EXCEPTION_NOT_HANDLED: DWORD = 0x80010001;
2078
2079         let mut child = Command::new("cmd")
2080             .creation_flags(DEBUG_PROCESS)
2081             .stdin(Stdio::piped())
2082             .spawn()
2083             .unwrap();
2084         child.stdin.take().unwrap().write_all(b"exit\r\n").unwrap();
2085         let mut events = 0;
2086         let mut event = DEBUG_EVENT { event_code: 0, process_id: 0, thread_id: 0, _junk: [0; 164] };
2087         loop {
2088             if unsafe { WaitForDebugEvent(&mut event as *mut DEBUG_EVENT, INFINITE) } == 0 {
2089                 panic!("WaitForDebugEvent failed!");
2090             }
2091             events += 1;
2092
2093             if event.event_code == EXIT_PROCESS_DEBUG_EVENT {
2094                 break;
2095             }
2096
2097             if unsafe {
2098                 ContinueDebugEvent(event.process_id, event.thread_id, DBG_EXCEPTION_NOT_HANDLED)
2099             } == 0
2100             {
2101                 panic!("ContinueDebugEvent failed!");
2102             }
2103         }
2104         assert!(events > 0);
2105     }
2106
2107     #[test]
2108     fn test_command_implements_send_sync() {
2109         fn take_send_sync_type<T: Send + Sync>(_: T) {}
2110         take_send_sync_type(Command::new(""))
2111     }
2112 }