tokio/process/
mod.rs

1//! An implementation of asynchronous process management for Tokio.
2//!
3//! This module provides a [`Command`] struct that imitates the interface of the
4//! [`std::process::Command`] type in the standard library, but provides asynchronous versions of
5//! functions that create processes. These functions (`spawn`, `status`, `output` and their
6//! variants) return "future aware" types that interoperate with Tokio. The asynchronous process
7//! support is provided through signal handling on Unix and system APIs on Windows.
8//!
9//! [`std::process::Command`]: std::process::Command
10//!
11//! # Examples
12//!
13//! Here's an example program which will spawn `echo hello world` and then wait
14//! for it complete.
15//!
16//! ```no_run
17//! use tokio::process::Command;
18//!
19//! #[tokio::main]
20//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
21//!     // The usage is similar as with the standard library's `Command` type
22//!     let mut child = Command::new("echo")
23//!         .arg("hello")
24//!         .arg("world")
25//!         .spawn()
26//!         .expect("failed to spawn");
27//!
28//!     // Await until the command completes
29//!     let status = child.wait().await?;
30//!     println!("the command exited with: {}", status);
31//!     Ok(())
32//! }
33//! ```
34//!
35//! Next, let's take a look at an example where we not only spawn `echo hello
36//! world` but we also capture its output.
37//!
38//! ```no_run
39//! use tokio::process::Command;
40//!
41//! #[tokio::main]
42//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
43//!     // Like above, but use `output` which returns a future instead of
44//!     // immediately returning the `Child`.
45//!     let output = Command::new("echo").arg("hello").arg("world")
46//!                         .output();
47//!
48//!     let output = output.await?;
49//!
50//!     assert!(output.status.success());
51//!     assert_eq!(output.stdout, b"hello world\n");
52//!     Ok(())
53//! }
54//! ```
55//!
56//! We can also read input line by line.
57//!
58//! ```no_run
59//! use tokio::io::{BufReader, AsyncBufReadExt};
60//! use tokio::process::Command;
61//!
62//! use std::process::Stdio;
63//!
64//! #[tokio::main]
65//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
66//!     let mut cmd = Command::new("cat");
67//!
68//!     // Specify that we want the command's standard output piped back to us.
69//!     // By default, standard input/output/error will be inherited from the
70//!     // current process (for example, this means that standard input will
71//!     // come from the keyboard and standard output/error will go directly to
72//!     // the terminal if this process is invoked from the command line).
73//!     cmd.stdout(Stdio::piped());
74//!
75//!     let mut child = cmd.spawn()
76//!         .expect("failed to spawn command");
77//!
78//!     let stdout = child.stdout.take()
79//!         .expect("child did not have a handle to stdout");
80//!
81//!     let mut reader = BufReader::new(stdout).lines();
82//!
83//!     // Ensure the child process is spawned in the runtime so it can
84//!     // make progress on its own while we await for any output.
85//!     tokio::spawn(async move {
86//!         let status = child.wait().await
87//!             .expect("child process encountered an error");
88//!
89//!         println!("child status was: {}", status);
90//!     });
91//!
92//!     while let Some(line) = reader.next_line().await? {
93//!         println!("Line: {}", line);
94//!     }
95//!
96//!     Ok(())
97//! }
98//! ```
99//!
100//! Here is another example using `sort` writing into the child process
101//! standard input, capturing the output of the sorted text.
102//!
103//! ```no_run
104//! use tokio::io::AsyncWriteExt;
105//! use tokio::process::Command;
106//!
107//! use std::process::Stdio;
108//!
109//! #[tokio::main]
110//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
111//!     let mut cmd = Command::new("sort");
112//!
113//!     // Specifying that we want pipe both the output and the input.
114//!     // Similarly to capturing the output, by configuring the pipe
115//!     // to stdin it can now be used as an asynchronous writer.
116//!     cmd.stdout(Stdio::piped());
117//!     cmd.stdin(Stdio::piped());
118//!
119//!     let mut child = cmd.spawn().expect("failed to spawn command");
120//!
121//!     // These are the animals we want to sort
122//!     let animals: &[&str] = &["dog", "bird", "frog", "cat", "fish"];
123//!
124//!     let mut stdin = child
125//!         .stdin
126//!         .take()
127//!         .expect("child did not have a handle to stdin");
128//!
129//!     // Write our animals to the child process
130//!     // Note that the behavior of `sort` is to buffer _all input_ before writing any output.
131//!     // In the general sense, it is recommended to write to the child in a separate task as
132//!     // awaiting its exit (or output) to avoid deadlocks (for example, the child tries to write
133//!     // some output but gets stuck waiting on the parent to read from it, meanwhile the parent
134//!     // is stuck waiting to write its input completely before reading the output).
135//!     stdin
136//!         .write(animals.join("\n").as_bytes())
137//!         .await
138//!         .expect("could not write to stdin");
139//!
140//!     // We drop the handle here which signals EOF to the child process.
141//!     // This tells the child process that it there is no more data on the pipe.
142//!     drop(stdin);
143//!
144//!     let op = child.wait_with_output().await?;
145//!
146//!     // Results should come back in sorted order
147//!     assert_eq!(op.stdout, "bird\ncat\ndog\nfish\nfrog\n".as_bytes());
148//!
149//!     Ok(())
150//! }
151//! ```
152//!
153//! With some coordination, we can also pipe the output of one command into
154//! another.
155//!
156//! ```no_run
157//! use tokio::join;
158//! use tokio::process::Command;
159//! use std::process::Stdio;
160//!
161//! #[tokio::main]
162//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
163//!     let mut echo = Command::new("echo")
164//!         .arg("hello world!")
165//!         .stdout(Stdio::piped())
166//!         .spawn()
167//!         .expect("failed to spawn echo");
168//!
169//!     let tr_stdin: Stdio = echo
170//!         .stdout
171//!         .take()
172//!         .unwrap()
173//!         .try_into()
174//!         .expect("failed to convert to Stdio");
175//!
176//!     let tr = Command::new("tr")
177//!         .arg("a-z")
178//!         .arg("A-Z")
179//!         .stdin(tr_stdin)
180//!         .stdout(Stdio::piped())
181//!         .spawn()
182//!         .expect("failed to spawn tr");
183//!
184//!     let (echo_result, tr_output) = join!(echo.wait(), tr.wait_with_output());
185//!
186//!     assert!(echo_result.unwrap().success());
187//!
188//!     let tr_output = tr_output.expect("failed to await tr");
189//!     assert!(tr_output.status.success());
190//!
191//!     assert_eq!(tr_output.stdout, b"HELLO WORLD!\n");
192//!
193//!     Ok(())
194//! }
195//! ```
196//!
197//! # Caveats
198//!
199//! ## Dropping/Cancellation
200//!
201//! Similar to the behavior to the standard library, and unlike the futures
202//! paradigm of dropping-implies-cancellation, a spawned process will, by
203//! default, continue to execute even after the `Child` handle has been dropped.
204//!
205//! The [`Command::kill_on_drop`] method can be used to modify this behavior
206//! and kill the child process if the `Child` wrapper is dropped before it
207//! has exited.
208//!
209//! ## Unix Processes
210//!
211//! On Unix platforms processes must be "reaped" by their parent process after
212//! they have exited in order to release all OS resources. A child process which
213//! has exited, but has not yet been reaped by its parent is considered a "zombie"
214//! process. Such processes continue to count against limits imposed by the system,
215//! and having too many zombie processes present can prevent additional processes
216//! from being spawned.
217//!
218//! The tokio runtime will, on a best-effort basis, attempt to reap and clean up
219//! any process which it has spawned. No additional guarantees are made with regard to
220//! how quickly or how often this procedure will take place.
221//!
222//! It is recommended to avoid dropping a [`Child`] process handle before it has been
223//! fully `await`ed if stricter cleanup guarantees are required.
224//!
225//! [`Command`]: crate::process::Command
226//! [`Command::kill_on_drop`]: crate::process::Command::kill_on_drop
227//! [`Child`]: crate::process::Child
228
229#[path = "unix/mod.rs"]
230#[cfg(unix)]
231mod imp;
232
233#[cfg(unix)]
234pub(crate) mod unix {
235    pub(crate) use super::imp::*;
236}
237
238#[path = "windows.rs"]
239#[cfg(windows)]
240mod imp;
241
242mod kill;
243
244use crate::io::{AsyncRead, AsyncWrite, ReadBuf};
245use crate::process::kill::Kill;
246
247use std::ffi::OsStr;
248use std::future::Future;
249use std::io;
250use std::path::Path;
251use std::pin::Pin;
252use std::process::{Child as StdChild, Command as StdCommand, ExitStatus, Output, Stdio};
253use std::task::{ready, Context, Poll};
254
255#[cfg(unix)]
256use std::os::unix::process::CommandExt;
257#[cfg(windows)]
258use std::os::windows::process::CommandExt;
259
260cfg_windows! {
261    use crate::os::windows::io::{AsRawHandle, RawHandle};
262}
263
264/// This structure mimics the API of [`std::process::Command`] found in the standard library, but
265/// replaces functions that create a process with an asynchronous variant. The main provided
266/// asynchronous functions are [spawn](Command::spawn), [status](Command::status), and
267/// [output](Command::output).
268///
269/// `Command` uses asynchronous versions of some `std` types (for example [`Child`]).
270///
271/// [`std::process::Command`]: std::process::Command
272/// [`Child`]: struct@Child
273#[derive(Debug)]
274pub struct Command {
275    std: StdCommand,
276    kill_on_drop: bool,
277}
278
279pub(crate) struct SpawnedChild {
280    child: imp::Child,
281    stdin: Option<imp::ChildStdio>,
282    stdout: Option<imp::ChildStdio>,
283    stderr: Option<imp::ChildStdio>,
284}
285
286impl Command {
287    /// Constructs a new `Command` for launching the program at
288    /// path `program`, with the following default configuration:
289    ///
290    /// * No arguments to the program
291    /// * Inherit the current process's environment
292    /// * Inherit the current process's working directory
293    /// * Inherit stdin/stdout/stderr for `spawn` or `status`, but create pipes for `output`
294    ///
295    /// Builder methods are provided to change these defaults and
296    /// otherwise configure the process.
297    ///
298    /// If `program` is not an absolute path, the `PATH` will be searched in
299    /// an OS-defined way.
300    ///
301    /// The search path to be used may be controlled by setting the
302    /// `PATH` environment variable on the Command,
303    /// but this has some implementation limitations on Windows
304    /// (see issue [rust-lang/rust#37519]).
305    ///
306    /// # Examples
307    ///
308    /// Basic usage:
309    ///
310    /// ```no_run
311    /// use tokio::process::Command;
312    /// let mut command = Command::new("sh");
313    /// # let _ = command.output(); // assert borrow checker
314    /// ```
315    ///
316    /// [rust-lang/rust#37519]: https://github.com/rust-lang/rust/issues/37519
317    pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
318        Self::from(StdCommand::new(program))
319    }
320
321    /// Cheaply convert to a `&std::process::Command` for places where the type from the standard
322    /// library is expected.
323    pub fn as_std(&self) -> &StdCommand {
324        &self.std
325    }
326
327    /// Cheaply convert to a `&mut std::process::Command` for places where the type from the
328    /// standard library is expected.
329    pub fn as_std_mut(&mut self) -> &mut StdCommand {
330        &mut self.std
331    }
332
333    /// Cheaply convert into a `std::process::Command`.
334    ///
335    /// Note that Tokio specific options will be lost. Currently, this only applies to [`kill_on_drop`].
336    ///
337    /// [`kill_on_drop`]: Command::kill_on_drop
338    pub fn into_std(self) -> StdCommand {
339        self.std
340    }
341
342    /// Adds an argument to pass to the program.
343    ///
344    /// Only one argument can be passed per use. So instead of:
345    ///
346    /// ```no_run
347    /// let mut command = tokio::process::Command::new("sh");
348    /// command.arg("-C /path/to/repo");
349    ///
350    /// # let _ = command.output(); // assert borrow checker
351    /// ```
352    ///
353    /// usage would be:
354    ///
355    /// ```no_run
356    /// let mut command = tokio::process::Command::new("sh");
357    /// command.arg("-C");
358    /// command.arg("/path/to/repo");
359    ///
360    /// # let _ = command.output(); // assert borrow checker
361    /// ```
362    ///
363    /// To pass multiple arguments see [`args`].
364    ///
365    /// [`args`]: method@Self::args
366    ///
367    /// # Examples
368    ///
369    /// Basic usage:
370    ///
371    /// ```no_run
372    /// # async fn test() { // allow using await
373    /// use tokio::process::Command;
374    ///
375    /// let output = Command::new("ls")
376    ///         .arg("-l")
377    ///         .arg("-a")
378    ///         .output().await.unwrap();
379    /// # }
380    ///
381    /// ```
382    pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {
383        self.std.arg(arg);
384        self
385    }
386
387    /// Adds multiple arguments to pass to the program.
388    ///
389    /// To pass a single argument see [`arg`].
390    ///
391    /// [`arg`]: method@Self::arg
392    ///
393    /// # Examples
394    ///
395    /// Basic usage:
396    ///
397    /// ```no_run
398    /// # async fn test() { // allow using await
399    /// use tokio::process::Command;
400    ///
401    /// let output = Command::new("ls")
402    ///         .args(&["-l", "-a"])
403    ///         .output().await.unwrap();
404    /// # }
405    /// ```
406    pub fn args<I, S>(&mut self, args: I) -> &mut Command
407    where
408        I: IntoIterator<Item = S>,
409        S: AsRef<OsStr>,
410    {
411        self.std.args(args);
412        self
413    }
414
415    cfg_windows! {
416        /// Append literal text to the command line without any quoting or escaping.
417        ///
418        /// This is useful for passing arguments to `cmd.exe /c`, which doesn't follow
419        /// `CommandLineToArgvW` escaping rules.
420        pub fn raw_arg<S: AsRef<OsStr>>(&mut self, text_to_append_as_is: S) -> &mut Command {
421            self.std.raw_arg(text_to_append_as_is);
422            self
423        }
424    }
425
426    /// Inserts or updates an environment variable mapping.
427    ///
428    /// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
429    /// and case-sensitive on all other platforms.
430    ///
431    /// # Examples
432    ///
433    /// Basic usage:
434    ///
435    /// ```no_run
436    /// # async fn test() { // allow using await
437    /// use tokio::process::Command;
438    ///
439    /// let output = Command::new("ls")
440    ///         .env("PATH", "/bin")
441    ///         .output().await.unwrap();
442    /// # }
443    /// ```
444    pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
445    where
446        K: AsRef<OsStr>,
447        V: AsRef<OsStr>,
448    {
449        self.std.env(key, val);
450        self
451    }
452
453    /// Adds or updates multiple environment variable mappings.
454    ///
455    /// # Examples
456    ///
457    /// Basic usage:
458    ///
459    /// ```no_run
460    /// # async fn test() { // allow using await
461    /// use tokio::process::Command;
462    /// use std::process::{Stdio};
463    /// use std::env;
464    /// use std::collections::HashMap;
465    ///
466    /// let filtered_env : HashMap<String, String> =
467    ///     env::vars().filter(|&(ref k, _)|
468    ///         k == "TERM" || k == "TZ" || k == "LANG" || k == "PATH"
469    ///     ).collect();
470    ///
471    /// let output = Command::new("printenv")
472    ///         .stdin(Stdio::null())
473    ///         .stdout(Stdio::inherit())
474    ///         .env_clear()
475    ///         .envs(&filtered_env)
476    ///         .output().await.unwrap();
477    /// # }
478    /// ```
479    pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command
480    where
481        I: IntoIterator<Item = (K, V)>,
482        K: AsRef<OsStr>,
483        V: AsRef<OsStr>,
484    {
485        self.std.envs(vars);
486        self
487    }
488
489    /// Removes an environment variable mapping.
490    ///
491    /// # Examples
492    ///
493    /// Basic usage:
494    ///
495    /// ```no_run
496    /// # async fn test() { // allow using await
497    /// use tokio::process::Command;
498    ///
499    /// let output = Command::new("ls")
500    ///         .env_remove("PATH")
501    ///         .output().await.unwrap();
502    /// # }
503    /// ```
504    pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
505        self.std.env_remove(key);
506        self
507    }
508
509    /// Clears the entire environment map for the child process.
510    ///
511    /// # Examples
512    ///
513    /// Basic usage:
514    ///
515    /// ```no_run
516    /// # async fn test() { // allow using await
517    /// use tokio::process::Command;
518    ///
519    /// let output = Command::new("ls")
520    ///         .env_clear()
521    ///         .output().await.unwrap();
522    /// # }
523    /// ```
524    pub fn env_clear(&mut self) -> &mut Command {
525        self.std.env_clear();
526        self
527    }
528
529    /// Sets the working directory for the child process.
530    ///
531    /// # Platform-specific behavior
532    ///
533    /// If the program path is relative (e.g., `"./script.sh"`), it's ambiguous
534    /// whether it should be interpreted relative to the parent's working
535    /// directory or relative to `current_dir`. The behavior in this case is
536    /// platform specific and unstable, and it's recommended to use
537    /// [`canonicalize`] to get an absolute program path instead.
538    ///
539    /// [`canonicalize`]: crate::fs::canonicalize()
540    ///
541    /// # Examples
542    ///
543    /// Basic usage:
544    ///
545    /// ```no_run
546    /// # async fn test() { // allow using await
547    /// use tokio::process::Command;
548    ///
549    /// let output = Command::new("ls")
550    ///         .current_dir("/bin")
551    ///         .output().await.unwrap();
552    /// # }
553    /// ```
554    pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command {
555        self.std.current_dir(dir);
556        self
557    }
558
559    /// Sets configuration for the child process's standard input (stdin) handle.
560    ///
561    /// Defaults to [`inherit`].
562    ///
563    /// [`inherit`]: std::process::Stdio::inherit
564    ///
565    /// # Examples
566    ///
567    /// Basic usage:
568    ///
569    /// ```no_run
570    /// # async fn test() { // allow using await
571    /// use std::process::{Stdio};
572    /// use tokio::process::Command;
573    ///
574    /// let output = Command::new("ls")
575    ///         .stdin(Stdio::null())
576    ///         .output().await.unwrap();
577    /// # }
578    /// ```
579    pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
580        self.std.stdin(cfg);
581        self
582    }
583
584    /// Sets configuration for the child process's standard output (stdout) handle.
585    ///
586    /// Defaults to [`inherit`] when used with `spawn` or `status`, and
587    /// defaults to [`piped`] when used with `output`.
588    ///
589    /// [`inherit`]: std::process::Stdio::inherit
590    /// [`piped`]: std::process::Stdio::piped
591    ///
592    /// # Examples
593    ///
594    /// Basic usage:
595    ///
596    /// ```no_run
597    /// # async fn test() { // allow using await
598    /// use tokio::process::Command;
599    /// use std::process::Stdio;
600    ///
601    /// let output = Command::new("ls")
602    ///         .stdout(Stdio::null())
603    ///         .output().await.unwrap();
604    /// # }
605    /// ```
606    pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
607        self.std.stdout(cfg);
608        self
609    }
610
611    /// Sets configuration for the child process's standard error (stderr) handle.
612    ///
613    /// Defaults to [`inherit`] when used with `spawn` or `status`, and
614    /// defaults to [`piped`] when used with `output`.
615    ///
616    /// [`inherit`]: std::process::Stdio::inherit
617    /// [`piped`]: std::process::Stdio::piped
618    ///
619    /// # Examples
620    ///
621    /// Basic usage:
622    ///
623    /// ```no_run
624    /// # async fn test() { // allow using await
625    /// use tokio::process::Command;
626    /// use std::process::{Stdio};
627    ///
628    /// let output = Command::new("ls")
629    ///         .stderr(Stdio::null())
630    ///         .output().await.unwrap();
631    /// # }
632    /// ```
633    pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
634        self.std.stderr(cfg);
635        self
636    }
637
638    /// Controls whether a `kill` operation should be invoked on a spawned child
639    /// process when its corresponding `Child` handle is dropped.
640    ///
641    /// By default, this value is assumed to be `false`, meaning the next spawned
642    /// process will not be killed on drop, similar to the behavior of the standard
643    /// library.
644    ///
645    /// # Caveats
646    ///
647    /// On Unix platforms processes must be "reaped" by their parent process after
648    /// they have exited in order to release all OS resources. A child process which
649    /// has exited, but has not yet been reaped by its parent is considered a "zombie"
650    /// process. Such processes continue to count against limits imposed by the system,
651    /// and having too many zombie processes present can prevent additional processes
652    /// from being spawned.
653    ///
654    /// Although issuing a `kill` signal to the child process is a synchronous
655    /// operation, the resulting zombie process cannot be `.await`ed inside of the
656    /// destructor to avoid blocking other tasks. The tokio runtime will, on a
657    /// best-effort basis, attempt to reap and clean up such processes in the
658    /// background, but no additional guarantees are made with regard to
659    /// how quickly or how often this procedure will take place.
660    ///
661    /// If stronger guarantees are required, it is recommended to avoid dropping
662    /// a [`Child`] handle where possible, and instead utilize `child.wait().await`
663    /// or `child.kill().await` where possible.
664    pub fn kill_on_drop(&mut self, kill_on_drop: bool) -> &mut Command {
665        self.kill_on_drop = kill_on_drop;
666        self
667    }
668
669    cfg_windows! {
670        /// Sets the [process creation flags][1] to be passed to `CreateProcess`.
671        ///
672        /// These will always be ORed with `CREATE_UNICODE_ENVIRONMENT`.
673        ///
674        /// [1]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx
675        pub fn creation_flags(&mut self, flags: u32) -> &mut Command {
676            self.std.creation_flags(flags);
677            self
678        }
679    }
680
681    /// Sets the child process's user ID. This translates to a
682    /// `setuid` call in the child process. Failure in the `setuid`
683    /// call will cause the spawn to fail.
684    #[cfg(unix)]
685    #[cfg_attr(docsrs, doc(cfg(unix)))]
686    pub fn uid(&mut self, id: u32) -> &mut Command {
687        #[cfg(target_os = "nto")]
688        let id = id as i32;
689        self.std.uid(id);
690        self
691    }
692
693    /// Similar to `uid` but sets the group ID of the child process. This has
694    /// the same semantics as the `uid` field.
695    #[cfg(unix)]
696    #[cfg_attr(docsrs, doc(cfg(unix)))]
697    pub fn gid(&mut self, id: u32) -> &mut Command {
698        #[cfg(target_os = "nto")]
699        let id = id as i32;
700        self.std.gid(id);
701        self
702    }
703
704    /// Sets executable argument.
705    ///
706    /// Set the first process argument, `argv[0]`, to something other than the
707    /// default executable path.
708    #[cfg(unix)]
709    #[cfg_attr(docsrs, doc(cfg(unix)))]
710    pub fn arg0<S>(&mut self, arg: S) -> &mut Command
711    where
712        S: AsRef<OsStr>,
713    {
714        self.std.arg0(arg);
715        self
716    }
717
718    /// Schedules a closure to be run just before the `exec` function is
719    /// invoked.
720    ///
721    /// The closure is allowed to return an I/O error whose OS error code will
722    /// be communicated back to the parent and returned as an error from when
723    /// the spawn was requested.
724    ///
725    /// Multiple closures can be registered and they will be called in order of
726    /// their registration. If a closure returns `Err` then no further closures
727    /// will be called and the spawn operation will immediately return with a
728    /// failure.
729    ///
730    /// # Safety
731    ///
732    /// This closure will be run in the context of the child process after a
733    /// `fork`. This primarily means that any modifications made to memory on
734    /// behalf of this closure will **not** be visible to the parent process.
735    /// This is often a very constrained environment where normal operations
736    /// like `malloc` or acquiring a mutex are not guaranteed to work (due to
737    /// other threads perhaps still running when the `fork` was run).
738    ///
739    /// This also means that all resources such as file descriptors and
740    /// memory-mapped regions got duplicated. It is your responsibility to make
741    /// sure that the closure does not violate library invariants by making
742    /// invalid use of these duplicates.
743    ///
744    /// When this closure is run, aspects such as the stdio file descriptors and
745    /// working directory have successfully been changed, so output to these
746    /// locations may not appear where intended.
747    #[cfg(unix)]
748    #[cfg_attr(docsrs, doc(cfg(unix)))]
749    pub unsafe fn pre_exec<F>(&mut self, f: F) -> &mut Command
750    where
751        F: FnMut() -> io::Result<()> + Send + Sync + 'static,
752    {
753        self.std.pre_exec(f);
754        self
755    }
756
757    /// Sets the process group ID (PGID) of the child process. Equivalent to a
758    /// `setpgid` call in the child process, but may be more efficient.
759    ///
760    /// Process groups determine which processes receive signals.
761    ///
762    /// # Examples
763    ///
764    /// Pressing Ctrl-C in a terminal will send `SIGINT` to all processes
765    /// in the current foreground process group. By spawning the `sleep`
766    /// subprocess in a new process group, it will not receive `SIGINT`
767    /// from the terminal.
768    ///
769    /// The parent process could install a [signal handler] and manage the
770    /// process on its own terms.
771    ///
772    /// A process group ID of 0 will use the process ID as the PGID.
773    ///
774    /// ```no_run
775    /// # async fn test() { // allow using await
776    /// use tokio::process::Command;
777    ///
778    /// let output = Command::new("sleep")
779    ///     .arg("10")
780    ///     .process_group(0)
781    ///     .output()
782    ///     .await
783    ///     .unwrap();
784    /// # }
785    /// ```
786    ///
787    /// [signal handler]: crate::signal
788    #[cfg(unix)]
789    #[cfg_attr(docsrs, doc(cfg(unix)))]
790    pub fn process_group(&mut self, pgroup: i32) -> &mut Command {
791        self.std.process_group(pgroup);
792        self
793    }
794
795    /// Executes the command as a child process, returning a handle to it.
796    ///
797    /// By default, stdin, stdout and stderr are inherited from the parent.
798    ///
799    /// This method will spawn the child process synchronously and return a
800    /// handle to a future-aware child process. The `Child` returned implements
801    /// `Future` itself to acquire the `ExitStatus` of the child, and otherwise
802    /// the `Child` has methods to acquire handles to the stdin, stdout, and
803    /// stderr streams.
804    ///
805    /// All I/O this child does will be associated with the current default
806    /// event loop.
807    ///
808    /// # Examples
809    ///
810    /// Basic usage:
811    ///
812    /// ```no_run
813    /// use tokio::process::Command;
814    ///
815    /// async fn run_ls() -> std::process::ExitStatus {
816    ///     Command::new("ls")
817    ///         .spawn()
818    ///         .expect("ls command failed to start")
819    ///         .wait()
820    ///         .await
821    ///         .expect("ls command failed to run")
822    /// }
823    /// ```
824    ///
825    /// # Caveats
826    ///
827    /// ## Dropping/Cancellation
828    ///
829    /// Similar to the behavior to the standard library, and unlike the futures
830    /// paradigm of dropping-implies-cancellation, a spawned process will, by
831    /// default, continue to execute even after the `Child` handle has been dropped.
832    ///
833    /// The [`Command::kill_on_drop`] method can be used to modify this behavior
834    /// and kill the child process if the `Child` wrapper is dropped before it
835    /// has exited.
836    ///
837    /// ## Unix Processes
838    ///
839    /// On Unix platforms processes must be "reaped" by their parent process after
840    /// they have exited in order to release all OS resources. A child process which
841    /// has exited, but has not yet been reaped by its parent is considered a "zombie"
842    /// process. Such processes continue to count against limits imposed by the system,
843    /// and having too many zombie processes present can prevent additional processes
844    /// from being spawned.
845    ///
846    /// The tokio runtime will, on a best-effort basis, attempt to reap and clean up
847    /// any process which it has spawned. No additional guarantees are made with regard to
848    /// how quickly or how often this procedure will take place.
849    ///
850    /// It is recommended to avoid dropping a [`Child`] process handle before it has been
851    /// fully `await`ed if stricter cleanup guarantees are required.
852    ///
853    /// [`Command`]: crate::process::Command
854    /// [`Command::kill_on_drop`]: crate::process::Command::kill_on_drop
855    /// [`Child`]: crate::process::Child
856    ///
857    /// # Errors
858    ///
859    /// On Unix platforms this method will fail with `std::io::ErrorKind::WouldBlock`
860    /// if the system process limit is reached (which includes other applications
861    /// running on the system).
862    #[inline]
863    pub fn spawn(&mut self) -> io::Result<Child> {
864        // On two lines to circumvent a mutable borrow check failure.
865        let child = self.std.spawn()?;
866        self.build_child(child)
867    }
868
869    /// Executes the command as a child process with a custom spawning function,
870    /// returning a handle to it.
871    ///
872    /// This is identical to [`Self::spawn`] in every aspect except the spawn:
873    /// here, it is customizable through the `with` parameter instead of
874    /// defaulting to the usual spawn. In fact, [`Self::spawn`] is just
875    /// [`Self::spawn_with`] with [`StdCommand::spawn`].
876    ///
877    /// This is useful mostly under Windows for now, since the platform exposes
878    /// special APIs to configure child processes when spawning them with various
879    /// attributes that customize the exact behavior of the spawn operation.
880    ///
881    /// # Examples
882    ///
883    /// Basic usage:
884    ///
885    /// ```no_run
886    /// # async fn test() { // allow using await
887    /// use std::process::Stdio;
888    ///
889    /// let output = tokio::process::Command::new("ls")
890    ///     .stdin(Stdio::null())
891    ///     .stdout(Stdio::piped())
892    ///     .stderr(Stdio::piped())
893    ///     .spawn_with(std::process::Command::spawn)
894    ///     .unwrap()
895    ///     .wait_with_output()
896    ///     .await
897    ///     .unwrap();
898    /// # }
899    /// ```
900    ///
901    /// Actually customizing the spawn under Windows:
902    ///
903    /// ```ignore
904    /// #![feature(windows_process_extensions_raw_attribute)]
905    /// # #[cfg(windows)]   // Windows-only nightly APIs are used here.
906    /// # async fn test() { // Allow using await.
907    /// use std::os::windows::process::{CommandExt, ProcThreadAttributeList};
908    /// use std::process::Stdio;
909    /// use tokio::process::Command;
910    ///
911    /// let parent = Command::new("cmd").spawn().unwrap();
912    /// let parent_process_handle = parent.raw_handle();
913    ///
914    /// const PROC_THREAD_ATTRIBUTE_PARENT_PROCESS: usize = 0x00020000;
915    /// let attribute_list = ProcThreadAttributeList::build()
916    ///     .attribute(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parent_process_handle)
917    ///     .finish()
918    ///     .unwrap();
919    ///
920    /// let _output = Command::new("ls")
921    ///     .stdin(Stdio::null())
922    ///     .stdout(Stdio::piped())
923    ///     .stderr(Stdio::piped())
924    ///     .spawn_with(|cmd| cmd.spawn_with_attributes(&attribute_list))
925    ///     .unwrap()
926    ///     .wait_with_output()
927    ///     .await
928    ///     .unwrap();
929    /// # }
930    /// ```
931    #[cfg(tokio_unstable)]
932    #[cfg_attr(docsrs, doc(cfg(tokio_unstable)))]
933    #[inline]
934    pub fn spawn_with(
935        &mut self,
936        with: impl Fn(&mut StdCommand) -> io::Result<StdChild>,
937    ) -> io::Result<Child> {
938        // On two lines to circumvent a mutable borrow check failure.
939        let child = with(&mut self.std)?;
940        self.build_child(child)
941    }
942
943    /// Small indirection for the spawn implementations.
944    ///
945    /// This is introduced for [`Self::spawn`] and [`Self::spawn_with`] to use:
946    /// [`Self::spawn`] cannot depend directly on on [`Self::spawn_with`] since
947    /// it is behind `tokio_unstable`. It also serves as a way to reduce
948    /// monomorphization bloat by taking in an already-spawned child process
949    /// instead of a command and custom spawn function.
950    fn build_child(&self, child: StdChild) -> io::Result<Child> {
951        let spawned_child = imp::build_child(child)?;
952
953        Ok(Child {
954            child: FusedChild::Child(ChildDropGuard {
955                inner: spawned_child.child,
956                kill_on_drop: self.kill_on_drop,
957            }),
958            stdin: spawned_child.stdin.map(|inner| ChildStdin { inner }),
959            stdout: spawned_child.stdout.map(|inner| ChildStdout { inner }),
960            stderr: spawned_child.stderr.map(|inner| ChildStderr { inner }),
961        })
962    }
963
964    /// Executes the command as a child process, waiting for it to finish and
965    /// collecting its exit status.
966    ///
967    /// By default, stdin, stdout and stderr are inherited from the parent.
968    /// If any input/output handles are set to a pipe then they will be immediately
969    /// closed after the child is spawned.
970    ///
971    /// All I/O this child does will be associated with the current default
972    /// event loop.
973    ///
974    /// The destructor of the future returned by this function will kill
975    /// the child if [`kill_on_drop`] is set to true.
976    ///
977    /// [`kill_on_drop`]: fn@Self::kill_on_drop
978    ///
979    /// # Errors
980    ///
981    /// This future will return an error if the child process cannot be spawned
982    /// or if there is an error while awaiting its status.
983    ///
984    /// On Unix platforms this method will fail with `std::io::ErrorKind::WouldBlock`
985    /// if the system process limit is reached (which includes other applications
986    /// running on the system).
987    ///
988    /// # Examples
989    ///
990    /// Basic usage:
991    ///
992    /// ```no_run
993    /// use tokio::process::Command;
994    ///
995    /// async fn run_ls() -> std::process::ExitStatus {
996    ///     Command::new("ls")
997    ///         .status()
998    ///         .await
999    ///         .expect("ls command failed to run")
1000    /// }
1001    /// ```
1002    pub fn status(&mut self) -> impl Future<Output = io::Result<ExitStatus>> {
1003        let child = self.spawn();
1004
1005        async {
1006            let mut child = child?;
1007
1008            // Ensure we close any stdio handles so we can't deadlock
1009            // waiting on the child which may be waiting to read/write
1010            // to a pipe we're holding.
1011            child.stdin.take();
1012            child.stdout.take();
1013            child.stderr.take();
1014
1015            child.wait().await
1016        }
1017    }
1018
1019    /// Executes the command as a child process, waiting for it to finish and
1020    /// collecting all of its output.
1021    ///
1022    /// > **Note**: this method, unlike the standard library, will
1023    /// > unconditionally configure the stdout/stderr handles to be pipes, even
1024    /// > if they have been previously configured. If this is not desired then
1025    /// > the `spawn` method should be used in combination with the
1026    /// > `wait_with_output` method on child.
1027    ///
1028    /// This method will return a future representing the collection of the
1029    /// child process's stdout/stderr. It will resolve to
1030    /// the `Output` type in the standard library, containing `stdout` and
1031    /// `stderr` as `Vec<u8>` along with an `ExitStatus` representing how the
1032    /// process exited.
1033    ///
1034    /// All I/O this child does will be associated with the current default
1035    /// event loop.
1036    ///
1037    /// The destructor of the future returned by this function will kill
1038    /// the child if [`kill_on_drop`] is set to true.
1039    ///
1040    /// [`kill_on_drop`]: fn@Self::kill_on_drop
1041    ///
1042    /// # Errors
1043    ///
1044    /// This future will return an error if the child process cannot be spawned
1045    /// or if there is an error while awaiting its status.
1046    ///
1047    /// On Unix platforms this method will fail with `std::io::ErrorKind::WouldBlock`
1048    /// if the system process limit is reached (which includes other applications
1049    /// running on the system).
1050    /// # Examples
1051    ///
1052    /// Basic usage:
1053    ///
1054    /// ```no_run
1055    /// use tokio::process::Command;
1056    ///
1057    /// async fn run_ls() {
1058    ///     let output: std::process::Output = Command::new("ls")
1059    ///         .output()
1060    ///         .await
1061    ///         .expect("ls command failed to run");
1062    ///     println!("stderr of ls: {:?}", output.stderr);
1063    /// }
1064    /// ```
1065    pub fn output(&mut self) -> impl Future<Output = io::Result<Output>> {
1066        self.std.stdout(Stdio::piped());
1067        self.std.stderr(Stdio::piped());
1068
1069        let child = self.spawn();
1070
1071        async { child?.wait_with_output().await }
1072    }
1073
1074    /// Returns the boolean value that was previously set by [`Command::kill_on_drop`].
1075    ///
1076    /// Note that if you have not previously called [`Command::kill_on_drop`], the
1077    /// default value of `false` will be returned here.
1078    ///
1079    /// # Examples
1080    ///
1081    /// ```
1082    /// use tokio::process::Command;
1083    ///
1084    /// let mut cmd = Command::new("echo");
1085    /// assert!(!cmd.get_kill_on_drop());
1086    ///
1087    /// cmd.kill_on_drop(true);
1088    /// assert!(cmd.get_kill_on_drop());
1089    /// ```
1090    pub fn get_kill_on_drop(&self) -> bool {
1091        self.kill_on_drop
1092    }
1093}
1094
1095impl From<StdCommand> for Command {
1096    fn from(std: StdCommand) -> Command {
1097        Command {
1098            std,
1099            kill_on_drop: false,
1100        }
1101    }
1102}
1103
1104/// A drop guard which can ensure the child process is killed on drop if specified.
1105#[derive(Debug)]
1106struct ChildDropGuard<T: Kill> {
1107    inner: T,
1108    kill_on_drop: bool,
1109}
1110
1111impl<T: Kill> Kill for ChildDropGuard<T> {
1112    fn kill(&mut self) -> io::Result<()> {
1113        let ret = self.inner.kill();
1114
1115        if ret.is_ok() {
1116            self.kill_on_drop = false;
1117        }
1118
1119        ret
1120    }
1121}
1122
1123impl<T: Kill> Drop for ChildDropGuard<T> {
1124    fn drop(&mut self) {
1125        if self.kill_on_drop {
1126            drop(self.kill());
1127        }
1128    }
1129}
1130
1131impl<T, E, F> Future for ChildDropGuard<F>
1132where
1133    F: Future<Output = Result<T, E>> + Kill + Unpin,
1134{
1135    type Output = Result<T, E>;
1136
1137    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1138        ready!(crate::trace::trace_leaf(cx));
1139        // Keep track of task budget
1140        let coop = ready!(crate::task::coop::poll_proceed(cx));
1141
1142        let ret = Pin::new(&mut self.inner).poll(cx);
1143
1144        if let Poll::Ready(Ok(_)) = ret {
1145            // Avoid the overhead of trying to kill a reaped process
1146            self.kill_on_drop = false;
1147        }
1148
1149        if ret.is_ready() {
1150            coop.made_progress();
1151        }
1152
1153        ret
1154    }
1155}
1156
1157/// Keeps track of the exit status of a child process without worrying about
1158/// polling the underlying futures even after they have completed.
1159#[derive(Debug)]
1160enum FusedChild {
1161    Child(ChildDropGuard<imp::Child>),
1162    Done(ExitStatus),
1163}
1164
1165/// Representation of a child process spawned onto an event loop.
1166///
1167/// # Caveats
1168/// Similar to the behavior to the standard library, and unlike the futures
1169/// paradigm of dropping-implies-cancellation, a spawned process will, by
1170/// default, continue to execute even after the `Child` handle has been dropped.
1171///
1172/// The `Command::kill_on_drop` method can be used to modify this behavior
1173/// and kill the child process if the `Child` wrapper is dropped before it
1174/// has exited.
1175#[derive(Debug)]
1176pub struct Child {
1177    child: FusedChild,
1178
1179    /// The handle for writing to the child's standard input (stdin), if it has
1180    /// been captured. To avoid partially moving the `child` and thus blocking
1181    /// yourself from calling functions on `child` while using `stdin`, you might
1182    /// find it helpful to do:
1183    ///
1184    /// ```no_run
1185    /// # let mut child = tokio::process::Command::new("echo").spawn().unwrap();
1186    /// let stdin = child.stdin.take().unwrap();
1187    /// ```
1188    pub stdin: Option<ChildStdin>,
1189
1190    /// The handle for reading from the child's standard output (stdout), if it
1191    /// has been captured. You might find it helpful to do
1192    ///
1193    /// ```no_run
1194    /// # let mut child = tokio::process::Command::new("echo").spawn().unwrap();
1195    /// let stdout = child.stdout.take().unwrap();
1196    /// ```
1197    ///
1198    /// to avoid partially moving the `child` and thus blocking yourself from calling
1199    /// functions on `child` while using `stdout`.
1200    pub stdout: Option<ChildStdout>,
1201
1202    /// The handle for reading from the child's standard error (stderr), if it
1203    /// has been captured. You might find it helpful to do
1204    ///
1205    /// ```no_run
1206    /// # let mut child = tokio::process::Command::new("echo").spawn().unwrap();
1207    /// let stderr = child.stderr.take().unwrap();
1208    /// ```
1209    ///
1210    /// to avoid partially moving the `child` and thus blocking yourself from calling
1211    /// functions on `child` while using `stderr`.
1212    pub stderr: Option<ChildStderr>,
1213}
1214
1215impl Child {
1216    /// Returns the OS-assigned process identifier associated with this child
1217    /// while it is still running.
1218    ///
1219    /// Once the child has been polled to completion this will return `None`.
1220    /// This is done to avoid confusion on platforms like Unix where the OS
1221    /// identifier could be reused once the process has completed.
1222    pub fn id(&self) -> Option<u32> {
1223        match &self.child {
1224            FusedChild::Child(child) => Some(child.inner.id()),
1225            FusedChild::Done(_) => None,
1226        }
1227    }
1228
1229    cfg_windows! {
1230        /// Extracts the raw handle of the process associated with this child while
1231        /// it is still running. Returns `None` if the child has exited.
1232        pub fn raw_handle(&self) -> Option<RawHandle> {
1233            match &self.child {
1234                FusedChild::Child(c) => Some(c.inner.as_raw_handle()),
1235                FusedChild::Done(_) => None,
1236            }
1237        }
1238    }
1239
1240    /// Attempts to force the child to exit, but does not wait for the request
1241    /// to take effect.
1242    ///
1243    /// On Unix platforms, this is the equivalent to sending a `SIGKILL`. Note
1244    /// that on Unix platforms it is possible for a zombie process to remain
1245    /// after a kill is sent; to avoid this, the caller should ensure that either
1246    /// `child.wait().await` or `child.try_wait()` is invoked successfully.
1247    pub fn start_kill(&mut self) -> io::Result<()> {
1248        match &mut self.child {
1249            FusedChild::Child(child) => child.kill(),
1250            FusedChild::Done(_) => Ok(()),
1251        }
1252    }
1253
1254    /// Forces the child to exit.
1255    ///
1256    /// This is equivalent to sending a `SIGKILL` on unix platforms
1257    /// followed by [`wait`](Child::wait).
1258    ///
1259    /// Note: std version of [`Child::kill`](std::process::Child::kill) does not `wait`.
1260    /// For an equivalent of `Child::kill` in the standard library,
1261    /// use [`start_kill`](Child::start_kill).
1262    ///
1263    /// # Examples
1264    ///
1265    /// If the child has to be killed remotely, it is possible to do it using
1266    /// a combination of the select! macro and a `oneshot` channel. In the following
1267    /// example, the child will run until completion unless a message is sent on
1268    /// the `oneshot` channel. If that happens, the child is killed immediately
1269    /// using the `.kill()` method.
1270    ///
1271    /// ```no_run
1272    /// use tokio::process::Command;
1273    /// use tokio::sync::oneshot::channel;
1274    ///
1275    /// #[tokio::main]
1276    /// async fn main() {
1277    ///     let (send, recv) = channel::<()>();
1278    ///     let mut child = Command::new("sleep").arg("1").spawn().unwrap();
1279    ///     tokio::spawn(async move { send.send(()) });
1280    ///     tokio::select! {
1281    ///         _ = child.wait() => {}
1282    ///         _ = recv => child.kill().await.expect("kill failed"),
1283    ///     }
1284    /// }
1285    /// ```
1286    ///
1287    /// You can also interact with the child's standard I/O. For example, you can
1288    /// read its stdout while waiting for it to exit.
1289    ///
1290    /// ```no_run
1291    /// # use std::process::Stdio;
1292    /// #
1293    /// # use tokio::io::AsyncReadExt;
1294    /// # use tokio::process::Command;
1295    /// # use tokio::sync::oneshot::channel;
1296    ///
1297    /// #[tokio::main]
1298    /// async fn main() {
1299    ///     let (_tx, rx) = channel::<()>();
1300    ///
1301    ///     let mut child = Command::new("echo")
1302    ///         .arg("Hello World!")
1303    ///         .stdout(Stdio::piped())
1304    ///         .spawn()
1305    ///         .unwrap();
1306    ///
1307    ///     let mut stdout = child.stdout.take().expect("stdout is not captured");
1308    ///
1309    ///     let read_stdout = tokio::spawn(async move {
1310    ///         let mut buff = Vec::new();
1311    ///         let _ = stdout.read_to_end(&mut buff).await;
1312    ///
1313    ///         buff
1314    ///     });
1315    ///
1316    ///     tokio::select! {
1317    ///         _ = child.wait() => {}
1318    ///         _ = rx => { child.kill().await.expect("kill failed") },
1319    ///     }
1320    ///
1321    ///     let buff = read_stdout.await.unwrap();
1322    ///
1323    ///     assert_eq!(buff, b"Hello World!\n");
1324    /// }
1325    /// ```
1326    pub async fn kill(&mut self) -> io::Result<()> {
1327        self.start_kill()?;
1328        self.wait().await?;
1329        Ok(())
1330    }
1331
1332    /// Waits for the child to exit completely, returning the status that it
1333    /// exited with. This function will continue to have the same return value
1334    /// after it has been called at least once.
1335    ///
1336    /// The stdin handle to the child process, if any, will be closed
1337    /// before waiting. This helps avoid deadlock: it ensures that the
1338    /// child does not block waiting for input from the parent, while
1339    /// the parent waits for the child to exit.
1340    ///
1341    /// If the caller wishes to explicitly control when the child's stdin
1342    /// handle is closed, they may `.take()` it before calling `.wait()`:
1343    ///
1344    /// # Cancel safety
1345    ///
1346    /// This function is cancel safe.
1347    ///
1348    /// ```
1349    /// # #[cfg(not(unix))]fn main(){}
1350    /// # #[cfg(unix)]
1351    /// use tokio::io::AsyncWriteExt;
1352    /// # #[cfg(unix)]
1353    /// use tokio::process::Command;
1354    /// # #[cfg(unix)]
1355    /// use std::process::Stdio;
1356    ///
1357    /// # #[cfg(unix)]
1358    /// #[tokio::main]
1359    /// async fn main() {
1360    /// #   if cfg!(miri) { return; } // No `pidfd_spawnp` in miri.
1361    ///     let mut child = Command::new("cat")
1362    ///         .stdin(Stdio::piped())
1363    ///         .spawn()
1364    ///         .unwrap();
1365    ///
1366    ///     let mut stdin = child.stdin.take().unwrap();
1367    ///     tokio::spawn(async move {
1368    ///         // do something with stdin here...
1369    ///         stdin.write_all(b"hello world\n").await.unwrap();
1370    ///
1371    ///         // then drop when finished
1372    ///         drop(stdin);
1373    ///     });
1374    ///
1375    ///     // wait for the process to complete
1376    ///     let _ = child.wait().await;
1377    /// }
1378    /// ```
1379    pub async fn wait(&mut self) -> io::Result<ExitStatus> {
1380        // Ensure stdin is closed so the child isn't stuck waiting on
1381        // input while the parent is waiting for it to exit.
1382        drop(self.stdin.take());
1383
1384        match &mut self.child {
1385            FusedChild::Done(exit) => Ok(*exit),
1386            FusedChild::Child(child) => {
1387                let ret = child.await;
1388
1389                if let Ok(exit) = ret {
1390                    self.child = FusedChild::Done(exit);
1391                }
1392
1393                ret
1394            }
1395        }
1396    }
1397
1398    /// Attempts to collect the exit status of the child if it has already
1399    /// exited.
1400    ///
1401    /// This function will not block the calling thread and will only
1402    /// check to see if the child process has exited or not. If the child has
1403    /// exited then on Unix the process ID is reaped. This function is
1404    /// guaranteed to repeatedly return a successful exit status so long as the
1405    /// child has already exited.
1406    ///
1407    /// If the child has exited, then `Ok(Some(status))` is returned. If the
1408    /// exit status is not available at this time then `Ok(None)` is returned.
1409    /// If an error occurs, then that error is returned.
1410    ///
1411    /// Note that unlike `wait`, this function will not attempt to drop stdin,
1412    /// nor will it wake the current task if the child exits.
1413    pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
1414        match &mut self.child {
1415            FusedChild::Done(exit) => Ok(Some(*exit)),
1416            FusedChild::Child(guard) => {
1417                let ret = guard.inner.try_wait();
1418
1419                if let Ok(Some(exit)) = ret {
1420                    // Avoid the overhead of trying to kill a reaped process
1421                    guard.kill_on_drop = false;
1422                    self.child = FusedChild::Done(exit);
1423                }
1424
1425                ret
1426            }
1427        }
1428    }
1429
1430    /// Returns a future that will resolve to an `Output`, containing the exit
1431    /// status, stdout, and stderr of the child process.
1432    ///
1433    /// The returned future will simultaneously waits for the child to exit and
1434    /// collect all remaining output on the stdout/stderr handles, returning an
1435    /// `Output` instance.
1436    ///
1437    /// The stdin handle to the child process, if any, will be closed before
1438    /// waiting. This helps avoid deadlock: it ensures that the child does not
1439    /// block waiting for input from the parent, while the parent waits for the
1440    /// child to exit.
1441    ///
1442    /// By default, stdin, stdout and stderr are inherited from the parent. In
1443    /// order to capture the output into this `Output` it is necessary to create
1444    /// new pipes between parent and child. Use `stdout(Stdio::piped())` or
1445    /// `stderr(Stdio::piped())`, respectively, when creating a `Command`.
1446    pub async fn wait_with_output(mut self) -> io::Result<Output> {
1447        use crate::future::try_join3;
1448
1449        async fn read_to_end<A: AsyncRead + Unpin>(io: &mut Option<A>) -> io::Result<Vec<u8>> {
1450            let mut vec = Vec::new();
1451            if let Some(io) = io.as_mut() {
1452                crate::io::util::read_to_end(io, &mut vec).await?;
1453            }
1454            Ok(vec)
1455        }
1456
1457        let mut stdout_pipe = self.stdout.take();
1458        let mut stderr_pipe = self.stderr.take();
1459
1460        let stdout_fut = read_to_end(&mut stdout_pipe);
1461        let stderr_fut = read_to_end(&mut stderr_pipe);
1462
1463        let (status, stdout, stderr) = try_join3(self.wait(), stdout_fut, stderr_fut).await?;
1464
1465        // Drop happens after `try_join` due to <https://github.com/tokio-rs/tokio/issues/4309>
1466        drop(stdout_pipe);
1467        drop(stderr_pipe);
1468
1469        Ok(Output {
1470            status,
1471            stdout,
1472            stderr,
1473        })
1474    }
1475}
1476
1477/// The standard input stream for spawned children.
1478///
1479/// This type implements the `AsyncWrite` trait to pass data to the stdin
1480/// handle of a child process asynchronously.
1481#[derive(Debug)]
1482pub struct ChildStdin {
1483    inner: imp::ChildStdio,
1484}
1485
1486/// The standard output stream for spawned children.
1487///
1488/// This type implements the `AsyncRead` trait to read data from the stdout
1489/// handle of a child process asynchronously.
1490#[derive(Debug)]
1491pub struct ChildStdout {
1492    inner: imp::ChildStdio,
1493}
1494
1495/// The standard error stream for spawned children.
1496///
1497/// This type implements the `AsyncRead` trait to read data from the stderr
1498/// handle of a child process asynchronously.
1499#[derive(Debug)]
1500pub struct ChildStderr {
1501    inner: imp::ChildStdio,
1502}
1503
1504impl ChildStdin {
1505    /// Creates an asynchronous `ChildStdin` from a synchronous one.
1506    ///
1507    /// # Errors
1508    ///
1509    /// This method may fail if an error is encountered when setting the pipe to
1510    /// non-blocking mode, or when registering the pipe with the runtime's IO
1511    /// driver.
1512    pub fn from_std(inner: std::process::ChildStdin) -> io::Result<Self> {
1513        Ok(Self {
1514            inner: imp::stdio(inner)?,
1515        })
1516    }
1517}
1518
1519impl ChildStdout {
1520    /// Creates an asynchronous `ChildStdout` from a synchronous one.
1521    ///
1522    /// # Errors
1523    ///
1524    /// This method may fail if an error is encountered when setting the pipe to
1525    /// non-blocking mode, or when registering the pipe with the runtime's IO
1526    /// driver.
1527    pub fn from_std(inner: std::process::ChildStdout) -> io::Result<Self> {
1528        Ok(Self {
1529            inner: imp::stdio(inner)?,
1530        })
1531    }
1532}
1533
1534impl ChildStderr {
1535    /// Creates an asynchronous `ChildStderr` from a synchronous one.
1536    ///
1537    /// # Errors
1538    ///
1539    /// This method may fail if an error is encountered when setting the pipe to
1540    /// non-blocking mode, or when registering the pipe with the runtime's IO
1541    /// driver.
1542    pub fn from_std(inner: std::process::ChildStderr) -> io::Result<Self> {
1543        Ok(Self {
1544            inner: imp::stdio(inner)?,
1545        })
1546    }
1547}
1548
1549impl AsyncWrite for ChildStdin {
1550    fn poll_write(
1551        mut self: Pin<&mut Self>,
1552        cx: &mut Context<'_>,
1553        buf: &[u8],
1554    ) -> Poll<io::Result<usize>> {
1555        Pin::new(&mut self.inner).poll_write(cx, buf)
1556    }
1557
1558    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1559        Pin::new(&mut self.inner).poll_flush(cx)
1560    }
1561
1562    fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1563        Pin::new(&mut self.inner).poll_shutdown(cx)
1564    }
1565
1566    fn poll_write_vectored(
1567        mut self: Pin<&mut Self>,
1568        cx: &mut Context<'_>,
1569        bufs: &[io::IoSlice<'_>],
1570    ) -> Poll<Result<usize, io::Error>> {
1571        Pin::new(&mut self.inner).poll_write_vectored(cx, bufs)
1572    }
1573
1574    fn is_write_vectored(&self) -> bool {
1575        self.inner.is_write_vectored()
1576    }
1577}
1578
1579impl AsyncRead for ChildStdout {
1580    fn poll_read(
1581        mut self: Pin<&mut Self>,
1582        cx: &mut Context<'_>,
1583        buf: &mut ReadBuf<'_>,
1584    ) -> Poll<io::Result<()>> {
1585        Pin::new(&mut self.inner).poll_read(cx, buf)
1586    }
1587}
1588
1589impl AsyncRead for ChildStderr {
1590    fn poll_read(
1591        mut self: Pin<&mut Self>,
1592        cx: &mut Context<'_>,
1593        buf: &mut ReadBuf<'_>,
1594    ) -> Poll<io::Result<()>> {
1595        Pin::new(&mut self.inner).poll_read(cx, buf)
1596    }
1597}
1598
1599impl TryInto<Stdio> for ChildStdin {
1600    type Error = io::Error;
1601
1602    fn try_into(self) -> Result<Stdio, Self::Error> {
1603        imp::convert_to_stdio(self.inner)
1604    }
1605}
1606
1607impl TryInto<Stdio> for ChildStdout {
1608    type Error = io::Error;
1609
1610    fn try_into(self) -> Result<Stdio, Self::Error> {
1611        imp::convert_to_stdio(self.inner)
1612    }
1613}
1614
1615impl TryInto<Stdio> for ChildStderr {
1616    type Error = io::Error;
1617
1618    fn try_into(self) -> Result<Stdio, Self::Error> {
1619        imp::convert_to_stdio(self.inner)
1620    }
1621}
1622
1623#[cfg(unix)]
1624#[cfg_attr(docsrs, doc(cfg(unix)))]
1625mod sys {
1626    use std::{
1627        io,
1628        os::unix::io::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd},
1629    };
1630
1631    use super::{ChildStderr, ChildStdin, ChildStdout};
1632
1633    macro_rules! impl_traits {
1634        ($type:ty) => {
1635            impl $type {
1636                /// Convert into [`OwnedFd`].
1637                pub fn into_owned_fd(self) -> io::Result<OwnedFd> {
1638                    self.inner.into_owned_fd()
1639                }
1640            }
1641
1642            impl AsRawFd for $type {
1643                fn as_raw_fd(&self) -> RawFd {
1644                    self.inner.as_raw_fd()
1645                }
1646            }
1647
1648            impl AsFd for $type {
1649                fn as_fd(&self) -> BorrowedFd<'_> {
1650                    unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
1651                }
1652            }
1653        };
1654    }
1655
1656    impl_traits!(ChildStdin);
1657    impl_traits!(ChildStdout);
1658    impl_traits!(ChildStderr);
1659}
1660
1661#[cfg(any(windows, docsrs))]
1662#[cfg_attr(docsrs, doc(cfg(windows)))]
1663mod windows {
1664    use super::*;
1665    use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, OwnedHandle, RawHandle};
1666
1667    #[cfg(not(docsrs))]
1668    macro_rules! impl_traits {
1669        ($type:ty) => {
1670            impl $type {
1671                /// Convert into [`OwnedHandle`].
1672                pub fn into_owned_handle(self) -> io::Result<OwnedHandle> {
1673                    self.inner.into_owned_handle()
1674                }
1675            }
1676
1677            impl AsRawHandle for $type {
1678                fn as_raw_handle(&self) -> RawHandle {
1679                    self.inner.as_raw_handle()
1680                }
1681            }
1682
1683            impl AsHandle for $type {
1684                fn as_handle(&self) -> BorrowedHandle<'_> {
1685                    unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
1686                }
1687            }
1688        };
1689    }
1690
1691    #[cfg(docsrs)]
1692    macro_rules! impl_traits {
1693        ($type:ty) => {
1694            impl $type {
1695                /// Convert into [`OwnedHandle`].
1696                pub fn into_owned_handle(self) -> io::Result<OwnedHandle> {
1697                    todo!("For doc generation only")
1698                }
1699            }
1700
1701            impl AsRawHandle for $type {
1702                fn as_raw_handle(&self) -> RawHandle {
1703                    todo!("For doc generation only")
1704                }
1705            }
1706
1707            impl AsHandle for $type {
1708                fn as_handle(&self) -> BorrowedHandle<'_> {
1709                    todo!("For doc generation only")
1710                }
1711            }
1712        };
1713    }
1714
1715    impl_traits!(ChildStdin);
1716    impl_traits!(ChildStdout);
1717    impl_traits!(ChildStderr);
1718}
1719
1720#[cfg(all(test, not(loom)))]
1721mod test {
1722    use super::kill::Kill;
1723    use super::ChildDropGuard;
1724
1725    use futures::future::FutureExt;
1726    use std::future::Future;
1727    use std::io;
1728    use std::pin::Pin;
1729    use std::task::{Context, Poll};
1730
1731    struct Mock {
1732        num_kills: usize,
1733        num_polls: usize,
1734        poll_result: Poll<Result<(), ()>>,
1735    }
1736
1737    impl Mock {
1738        fn new() -> Self {
1739            Self::with_result(Poll::Pending)
1740        }
1741
1742        fn with_result(result: Poll<Result<(), ()>>) -> Self {
1743            Self {
1744                num_kills: 0,
1745                num_polls: 0,
1746                poll_result: result,
1747            }
1748        }
1749    }
1750
1751    impl Kill for Mock {
1752        fn kill(&mut self) -> io::Result<()> {
1753            self.num_kills += 1;
1754            Ok(())
1755        }
1756    }
1757
1758    impl Future for Mock {
1759        type Output = Result<(), ()>;
1760
1761        fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
1762            let inner = Pin::get_mut(self);
1763            inner.num_polls += 1;
1764            inner.poll_result
1765        }
1766    }
1767
1768    #[test]
1769    fn kills_on_drop_if_specified() {
1770        let mut mock = Mock::new();
1771
1772        {
1773            let guard = ChildDropGuard {
1774                inner: &mut mock,
1775                kill_on_drop: true,
1776            };
1777            drop(guard);
1778        }
1779
1780        assert_eq!(1, mock.num_kills);
1781        assert_eq!(0, mock.num_polls);
1782    }
1783
1784    #[test]
1785    fn no_kill_on_drop_by_default() {
1786        let mut mock = Mock::new();
1787
1788        {
1789            let guard = ChildDropGuard {
1790                inner: &mut mock,
1791                kill_on_drop: false,
1792            };
1793            drop(guard);
1794        }
1795
1796        assert_eq!(0, mock.num_kills);
1797        assert_eq!(0, mock.num_polls);
1798    }
1799
1800    #[test]
1801    fn no_kill_if_already_killed() {
1802        let mut mock = Mock::new();
1803
1804        {
1805            let mut guard = ChildDropGuard {
1806                inner: &mut mock,
1807                kill_on_drop: true,
1808            };
1809            let _ = guard.kill();
1810            drop(guard);
1811        }
1812
1813        assert_eq!(1, mock.num_kills);
1814        assert_eq!(0, mock.num_polls);
1815    }
1816
1817    #[test]
1818    fn no_kill_if_reaped() {
1819        let mut mock_pending = Mock::with_result(Poll::Pending);
1820        let mut mock_reaped = Mock::with_result(Poll::Ready(Ok(())));
1821        let mut mock_err = Mock::with_result(Poll::Ready(Err(())));
1822
1823        let waker = futures::task::noop_waker();
1824        let mut context = Context::from_waker(&waker);
1825        {
1826            let mut guard = ChildDropGuard {
1827                inner: &mut mock_pending,
1828                kill_on_drop: true,
1829            };
1830            let _ = guard.poll_unpin(&mut context);
1831
1832            let mut guard = ChildDropGuard {
1833                inner: &mut mock_reaped,
1834                kill_on_drop: true,
1835            };
1836            let _ = guard.poll_unpin(&mut context);
1837
1838            let mut guard = ChildDropGuard {
1839                inner: &mut mock_err,
1840                kill_on_drop: true,
1841            };
1842            let _ = guard.poll_unpin(&mut context);
1843        }
1844
1845        assert_eq!(1, mock_pending.num_kills);
1846        assert_eq!(1, mock_pending.num_polls);
1847
1848        assert_eq!(0, mock_reaped.num_kills);
1849        assert_eq!(1, mock_reaped.num_polls);
1850
1851        assert_eq!(1, mock_err.num_kills);
1852        assert_eq!(1, mock_err.num_polls);
1853    }
1854}