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::{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    /// Adds an argument to pass to the program.
334    ///
335    /// Only one argument can be passed per use. So instead of:
336    ///
337    /// ```no_run
338    /// let mut command = tokio::process::Command::new("sh");
339    /// command.arg("-C /path/to/repo");
340    ///
341    /// # let _ = command.output(); // assert borrow checker
342    /// ```
343    ///
344    /// usage would be:
345    ///
346    /// ```no_run
347    /// let mut command = tokio::process::Command::new("sh");
348    /// command.arg("-C");
349    /// command.arg("/path/to/repo");
350    ///
351    /// # let _ = command.output(); // assert borrow checker
352    /// ```
353    ///
354    /// To pass multiple arguments see [`args`].
355    ///
356    /// [`args`]: method@Self::args
357    ///
358    /// # Examples
359    ///
360    /// Basic usage:
361    ///
362    /// ```no_run
363    /// # async fn test() { // allow using await
364    /// use tokio::process::Command;
365    ///
366    /// let output = Command::new("ls")
367    ///         .arg("-l")
368    ///         .arg("-a")
369    ///         .output().await.unwrap();
370    /// # }
371    ///
372    /// ```
373    pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {
374        self.std.arg(arg);
375        self
376    }
377
378    /// Adds multiple arguments to pass to the program.
379    ///
380    /// To pass a single argument see [`arg`].
381    ///
382    /// [`arg`]: method@Self::arg
383    ///
384    /// # Examples
385    ///
386    /// Basic usage:
387    ///
388    /// ```no_run
389    /// # async fn test() { // allow using await
390    /// use tokio::process::Command;
391    ///
392    /// let output = Command::new("ls")
393    ///         .args(&["-l", "-a"])
394    ///         .output().await.unwrap();
395    /// # }
396    /// ```
397    pub fn args<I, S>(&mut self, args: I) -> &mut Command
398    where
399        I: IntoIterator<Item = S>,
400        S: AsRef<OsStr>,
401    {
402        self.std.args(args);
403        self
404    }
405
406    cfg_windows! {
407        /// Append literal text to the command line without any quoting or escaping.
408        ///
409        /// This is useful for passing arguments to `cmd.exe /c`, which doesn't follow
410        /// `CommandLineToArgvW` escaping rules.
411        pub fn raw_arg<S: AsRef<OsStr>>(&mut self, text_to_append_as_is: S) -> &mut Command {
412            self.std.raw_arg(text_to_append_as_is);
413            self
414        }
415    }
416
417    /// Inserts or updates an environment variable mapping.
418    ///
419    /// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
420    /// and case-sensitive on all other platforms.
421    ///
422    /// # Examples
423    ///
424    /// Basic usage:
425    ///
426    /// ```no_run
427    /// # async fn test() { // allow using await
428    /// use tokio::process::Command;
429    ///
430    /// let output = Command::new("ls")
431    ///         .env("PATH", "/bin")
432    ///         .output().await.unwrap();
433    /// # }
434    /// ```
435    pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
436    where
437        K: AsRef<OsStr>,
438        V: AsRef<OsStr>,
439    {
440        self.std.env(key, val);
441        self
442    }
443
444    /// Adds or updates multiple environment variable mappings.
445    ///
446    /// # Examples
447    ///
448    /// Basic usage:
449    ///
450    /// ```no_run
451    /// # async fn test() { // allow using await
452    /// use tokio::process::Command;
453    /// use std::process::{Stdio};
454    /// use std::env;
455    /// use std::collections::HashMap;
456    ///
457    /// let filtered_env : HashMap<String, String> =
458    ///     env::vars().filter(|&(ref k, _)|
459    ///         k == "TERM" || k == "TZ" || k == "LANG" || k == "PATH"
460    ///     ).collect();
461    ///
462    /// let output = Command::new("printenv")
463    ///         .stdin(Stdio::null())
464    ///         .stdout(Stdio::inherit())
465    ///         .env_clear()
466    ///         .envs(&filtered_env)
467    ///         .output().await.unwrap();
468    /// # }
469    /// ```
470    pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command
471    where
472        I: IntoIterator<Item = (K, V)>,
473        K: AsRef<OsStr>,
474        V: AsRef<OsStr>,
475    {
476        self.std.envs(vars);
477        self
478    }
479
480    /// Removes an environment variable mapping.
481    ///
482    /// # Examples
483    ///
484    /// Basic usage:
485    ///
486    /// ```no_run
487    /// # async fn test() { // allow using await
488    /// use tokio::process::Command;
489    ///
490    /// let output = Command::new("ls")
491    ///         .env_remove("PATH")
492    ///         .output().await.unwrap();
493    /// # }
494    /// ```
495    pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
496        self.std.env_remove(key);
497        self
498    }
499
500    /// Clears the entire environment map for the child process.
501    ///
502    /// # Examples
503    ///
504    /// Basic usage:
505    ///
506    /// ```no_run
507    /// # async fn test() { // allow using await
508    /// use tokio::process::Command;
509    ///
510    /// let output = Command::new("ls")
511    ///         .env_clear()
512    ///         .output().await.unwrap();
513    /// # }
514    /// ```
515    pub fn env_clear(&mut self) -> &mut Command {
516        self.std.env_clear();
517        self
518    }
519
520    /// Sets the working directory for the child process.
521    ///
522    /// # Platform-specific behavior
523    ///
524    /// If the program path is relative (e.g., `"./script.sh"`), it's ambiguous
525    /// whether it should be interpreted relative to the parent's working
526    /// directory or relative to `current_dir`. The behavior in this case is
527    /// platform specific and unstable, and it's recommended to use
528    /// [`canonicalize`] to get an absolute program path instead.
529    ///
530    /// [`canonicalize`]: crate::fs::canonicalize()
531    ///
532    /// # Examples
533    ///
534    /// Basic usage:
535    ///
536    /// ```no_run
537    /// # async fn test() { // allow using await
538    /// use tokio::process::Command;
539    ///
540    /// let output = Command::new("ls")
541    ///         .current_dir("/bin")
542    ///         .output().await.unwrap();
543    /// # }
544    /// ```
545    pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command {
546        self.std.current_dir(dir);
547        self
548    }
549
550    /// Sets configuration for the child process's standard input (stdin) handle.
551    ///
552    /// Defaults to [`inherit`].
553    ///
554    /// [`inherit`]: std::process::Stdio::inherit
555    ///
556    /// # Examples
557    ///
558    /// Basic usage:
559    ///
560    /// ```no_run
561    /// # async fn test() { // allow using await
562    /// use std::process::{Stdio};
563    /// use tokio::process::Command;
564    ///
565    /// let output = Command::new("ls")
566    ///         .stdin(Stdio::null())
567    ///         .output().await.unwrap();
568    /// # }
569    /// ```
570    pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
571        self.std.stdin(cfg);
572        self
573    }
574
575    /// Sets configuration for the child process's standard output (stdout) handle.
576    ///
577    /// Defaults to [`inherit`] when used with `spawn` or `status`, and
578    /// defaults to [`piped`] when used with `output`.
579    ///
580    /// [`inherit`]: std::process::Stdio::inherit
581    /// [`piped`]: std::process::Stdio::piped
582    ///
583    /// # Examples
584    ///
585    /// Basic usage:
586    ///
587    /// ```no_run
588    /// # async fn test() { // allow using await
589    /// use tokio::process::Command;
590    /// use std::process::Stdio;
591    ///
592    /// let output = Command::new("ls")
593    ///         .stdout(Stdio::null())
594    ///         .output().await.unwrap();
595    /// # }
596    /// ```
597    pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
598        self.std.stdout(cfg);
599        self
600    }
601
602    /// Sets configuration for the child process's standard error (stderr) handle.
603    ///
604    /// Defaults to [`inherit`] when used with `spawn` or `status`, and
605    /// defaults to [`piped`] when used with `output`.
606    ///
607    /// [`inherit`]: std::process::Stdio::inherit
608    /// [`piped`]: std::process::Stdio::piped
609    ///
610    /// # Examples
611    ///
612    /// Basic usage:
613    ///
614    /// ```no_run
615    /// # async fn test() { // allow using await
616    /// use tokio::process::Command;
617    /// use std::process::{Stdio};
618    ///
619    /// let output = Command::new("ls")
620    ///         .stderr(Stdio::null())
621    ///         .output().await.unwrap();
622    /// # }
623    /// ```
624    pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
625        self.std.stderr(cfg);
626        self
627    }
628
629    /// Controls whether a `kill` operation should be invoked on a spawned child
630    /// process when its corresponding `Child` handle is dropped.
631    ///
632    /// By default, this value is assumed to be `false`, meaning the next spawned
633    /// process will not be killed on drop, similar to the behavior of the standard
634    /// library.
635    ///
636    /// # Caveats
637    ///
638    /// On Unix platforms processes must be "reaped" by their parent process after
639    /// they have exited in order to release all OS resources. A child process which
640    /// has exited, but has not yet been reaped by its parent is considered a "zombie"
641    /// process. Such processes continue to count against limits imposed by the system,
642    /// and having too many zombie processes present can prevent additional processes
643    /// from being spawned.
644    ///
645    /// Although issuing a `kill` signal to the child process is a synchronous
646    /// operation, the resulting zombie process cannot be `.await`ed inside of the
647    /// destructor to avoid blocking other tasks. The tokio runtime will, on a
648    /// best-effort basis, attempt to reap and clean up such processes in the
649    /// background, but no additional guarantees are made with regard to
650    /// how quickly or how often this procedure will take place.
651    ///
652    /// If stronger guarantees are required, it is recommended to avoid dropping
653    /// a [`Child`] handle where possible, and instead utilize `child.wait().await`
654    /// or `child.kill().await` where possible.
655    pub fn kill_on_drop(&mut self, kill_on_drop: bool) -> &mut Command {
656        self.kill_on_drop = kill_on_drop;
657        self
658    }
659
660    cfg_windows! {
661        /// Sets the [process creation flags][1] to be passed to `CreateProcess`.
662        ///
663        /// These will always be ORed with `CREATE_UNICODE_ENVIRONMENT`.
664        ///
665        /// [1]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx
666        pub fn creation_flags(&mut self, flags: u32) -> &mut Command {
667            self.std.creation_flags(flags);
668            self
669        }
670    }
671
672    /// Sets the child process's user ID. This translates to a
673    /// `setuid` call in the child process. Failure in the `setuid`
674    /// call will cause the spawn to fail.
675    #[cfg(unix)]
676    #[cfg_attr(docsrs, doc(cfg(unix)))]
677    pub fn uid(&mut self, id: u32) -> &mut Command {
678        #[cfg(target_os = "nto")]
679        let id = id as i32;
680        self.std.uid(id);
681        self
682    }
683
684    /// Similar to `uid` but sets the group ID of the child process. This has
685    /// the same semantics as the `uid` field.
686    #[cfg(unix)]
687    #[cfg_attr(docsrs, doc(cfg(unix)))]
688    pub fn gid(&mut self, id: u32) -> &mut Command {
689        #[cfg(target_os = "nto")]
690        let id = id as i32;
691        self.std.gid(id);
692        self
693    }
694
695    /// Sets executable argument.
696    ///
697    /// Set the first process argument, `argv[0]`, to something other than the
698    /// default executable path.
699    #[cfg(unix)]
700    #[cfg_attr(docsrs, doc(cfg(unix)))]
701    pub fn arg0<S>(&mut self, arg: S) -> &mut Command
702    where
703        S: AsRef<OsStr>,
704    {
705        self.std.arg0(arg);
706        self
707    }
708
709    /// Schedules a closure to be run just before the `exec` function is
710    /// invoked.
711    ///
712    /// The closure is allowed to return an I/O error whose OS error code will
713    /// be communicated back to the parent and returned as an error from when
714    /// the spawn was requested.
715    ///
716    /// Multiple closures can be registered and they will be called in order of
717    /// their registration. If a closure returns `Err` then no further closures
718    /// will be called and the spawn operation will immediately return with a
719    /// failure.
720    ///
721    /// # Safety
722    ///
723    /// This closure will be run in the context of the child process after a
724    /// `fork`. This primarily means that any modifications made to memory on
725    /// behalf of this closure will **not** be visible to the parent process.
726    /// This is often a very constrained environment where normal operations
727    /// like `malloc` or acquiring a mutex are not guaranteed to work (due to
728    /// other threads perhaps still running when the `fork` was run).
729    ///
730    /// This also means that all resources such as file descriptors and
731    /// memory-mapped regions got duplicated. It is your responsibility to make
732    /// sure that the closure does not violate library invariants by making
733    /// invalid use of these duplicates.
734    ///
735    /// When this closure is run, aspects such as the stdio file descriptors and
736    /// working directory have successfully been changed, so output to these
737    /// locations may not appear where intended.
738    #[cfg(unix)]
739    #[cfg_attr(docsrs, doc(cfg(unix)))]
740    pub unsafe fn pre_exec<F>(&mut self, f: F) -> &mut Command
741    where
742        F: FnMut() -> io::Result<()> + Send + Sync + 'static,
743    {
744        self.std.pre_exec(f);
745        self
746    }
747
748    /// Sets the process group ID (PGID) of the child process. Equivalent to a
749    /// `setpgid` call in the child process, but may be more efficient.
750    ///
751    /// Process groups determine which processes receive signals.
752    ///
753    /// # Examples
754    ///
755    /// Pressing Ctrl-C in a terminal will send `SIGINT` to all processes
756    /// in the current foreground process group. By spawning the `sleep`
757    /// subprocess in a new process group, it will not receive `SIGINT`
758    /// from the terminal.
759    ///
760    /// The parent process could install a [signal handler] and manage the
761    /// process on its own terms.
762    ///
763    /// A process group ID of 0 will use the process ID as the PGID.
764    ///
765    /// ```no_run
766    /// # async fn test() { // allow using await
767    /// use tokio::process::Command;
768    ///
769    /// let output = Command::new("sleep")
770    ///     .arg("10")
771    ///     .process_group(0)
772    ///     .output()
773    ///     .await
774    ///     .unwrap();
775    /// # }
776    /// ```
777    ///
778    /// [signal handler]: crate::signal
779    #[cfg(unix)]
780    #[cfg_attr(docsrs, doc(cfg(unix)))]
781    pub fn process_group(&mut self, pgroup: i32) -> &mut Command {
782        self.std.process_group(pgroup);
783        self
784    }
785
786    /// Executes the command as a child process, returning a handle to it.
787    ///
788    /// By default, stdin, stdout and stderr are inherited from the parent.
789    ///
790    /// This method will spawn the child process synchronously and return a
791    /// handle to a future-aware child process. The `Child` returned implements
792    /// `Future` itself to acquire the `ExitStatus` of the child, and otherwise
793    /// the `Child` has methods to acquire handles to the stdin, stdout, and
794    /// stderr streams.
795    ///
796    /// All I/O this child does will be associated with the current default
797    /// event loop.
798    ///
799    /// # Examples
800    ///
801    /// Basic usage:
802    ///
803    /// ```no_run
804    /// use tokio::process::Command;
805    ///
806    /// async fn run_ls() -> std::process::ExitStatus {
807    ///     Command::new("ls")
808    ///         .spawn()
809    ///         .expect("ls command failed to start")
810    ///         .wait()
811    ///         .await
812    ///         .expect("ls command failed to run")
813    /// }
814    /// ```
815    ///
816    /// # Caveats
817    ///
818    /// ## Dropping/Cancellation
819    ///
820    /// Similar to the behavior to the standard library, and unlike the futures
821    /// paradigm of dropping-implies-cancellation, a spawned process will, by
822    /// default, continue to execute even after the `Child` handle has been dropped.
823    ///
824    /// The [`Command::kill_on_drop`] method can be used to modify this behavior
825    /// and kill the child process if the `Child` wrapper is dropped before it
826    /// has exited.
827    ///
828    /// ## Unix Processes
829    ///
830    /// On Unix platforms processes must be "reaped" by their parent process after
831    /// they have exited in order to release all OS resources. A child process which
832    /// has exited, but has not yet been reaped by its parent is considered a "zombie"
833    /// process. Such processes continue to count against limits imposed by the system,
834    /// and having too many zombie processes present can prevent additional processes
835    /// from being spawned.
836    ///
837    /// The tokio runtime will, on a best-effort basis, attempt to reap and clean up
838    /// any process which it has spawned. No additional guarantees are made with regard to
839    /// how quickly or how often this procedure will take place.
840    ///
841    /// It is recommended to avoid dropping a [`Child`] process handle before it has been
842    /// fully `await`ed if stricter cleanup guarantees are required.
843    ///
844    /// [`Command`]: crate::process::Command
845    /// [`Command::kill_on_drop`]: crate::process::Command::kill_on_drop
846    /// [`Child`]: crate::process::Child
847    ///
848    /// # Errors
849    ///
850    /// On Unix platforms this method will fail with `std::io::ErrorKind::WouldBlock`
851    /// if the system process limit is reached (which includes other applications
852    /// running on the system).
853    pub fn spawn(&mut self) -> io::Result<Child> {
854        imp::spawn_child(&mut self.std).map(|spawned_child| Child {
855            child: FusedChild::Child(ChildDropGuard {
856                inner: spawned_child.child,
857                kill_on_drop: self.kill_on_drop,
858            }),
859            stdin: spawned_child.stdin.map(|inner| ChildStdin { inner }),
860            stdout: spawned_child.stdout.map(|inner| ChildStdout { inner }),
861            stderr: spawned_child.stderr.map(|inner| ChildStderr { inner }),
862        })
863    }
864
865    /// Executes the command as a child process, waiting for it to finish and
866    /// collecting its exit status.
867    ///
868    /// By default, stdin, stdout and stderr are inherited from the parent.
869    /// If any input/output handles are set to a pipe then they will be immediately
870    /// closed after the child is spawned.
871    ///
872    /// All I/O this child does will be associated with the current default
873    /// event loop.
874    ///
875    /// The destructor of the future returned by this function will kill
876    /// the child if [`kill_on_drop`] is set to true.
877    ///
878    /// [`kill_on_drop`]: fn@Self::kill_on_drop
879    ///
880    /// # Errors
881    ///
882    /// This future will return an error if the child process cannot be spawned
883    /// or if there is an error while awaiting its status.
884    ///
885    /// On Unix platforms this method will fail with `std::io::ErrorKind::WouldBlock`
886    /// if the system process limit is reached (which includes other applications
887    /// running on the system).
888    ///
889    /// # Examples
890    ///
891    /// Basic usage:
892    ///
893    /// ```no_run
894    /// use tokio::process::Command;
895    ///
896    /// async fn run_ls() -> std::process::ExitStatus {
897    ///     Command::new("ls")
898    ///         .status()
899    ///         .await
900    ///         .expect("ls command failed to run")
901    /// }
902    /// ```
903    pub fn status(&mut self) -> impl Future<Output = io::Result<ExitStatus>> {
904        let child = self.spawn();
905
906        async {
907            let mut child = child?;
908
909            // Ensure we close any stdio handles so we can't deadlock
910            // waiting on the child which may be waiting to read/write
911            // to a pipe we're holding.
912            child.stdin.take();
913            child.stdout.take();
914            child.stderr.take();
915
916            child.wait().await
917        }
918    }
919
920    /// Executes the command as a child process, waiting for it to finish and
921    /// collecting all of its output.
922    ///
923    /// > **Note**: this method, unlike the standard library, will
924    /// > unconditionally configure the stdout/stderr handles to be pipes, even
925    /// > if they have been previously configured. If this is not desired then
926    /// > the `spawn` method should be used in combination with the
927    /// > `wait_with_output` method on child.
928    ///
929    /// This method will return a future representing the collection of the
930    /// child process's stdout/stderr. It will resolve to
931    /// the `Output` type in the standard library, containing `stdout` and
932    /// `stderr` as `Vec<u8>` along with an `ExitStatus` representing how the
933    /// process exited.
934    ///
935    /// All I/O this child does will be associated with the current default
936    /// event loop.
937    ///
938    /// The destructor of the future returned by this function will kill
939    /// the child if [`kill_on_drop`] is set to true.
940    ///
941    /// [`kill_on_drop`]: fn@Self::kill_on_drop
942    ///
943    /// # Errors
944    ///
945    /// This future will return an error if the child process cannot be spawned
946    /// or if there is an error while awaiting its status.
947    ///
948    /// On Unix platforms this method will fail with `std::io::ErrorKind::WouldBlock`
949    /// if the system process limit is reached (which includes other applications
950    /// running on the system).
951    /// # Examples
952    ///
953    /// Basic usage:
954    ///
955    /// ```no_run
956    /// use tokio::process::Command;
957    ///
958    /// async fn run_ls() {
959    ///     let output: std::process::Output = Command::new("ls")
960    ///         .output()
961    ///         .await
962    ///         .expect("ls command failed to run");
963    ///     println!("stderr of ls: {:?}", output.stderr);
964    /// }
965    /// ```
966    pub fn output(&mut self) -> impl Future<Output = io::Result<Output>> {
967        self.std.stdout(Stdio::piped());
968        self.std.stderr(Stdio::piped());
969
970        let child = self.spawn();
971
972        async { child?.wait_with_output().await }
973    }
974}
975
976impl From<StdCommand> for Command {
977    fn from(std: StdCommand) -> Command {
978        Command {
979            std,
980            kill_on_drop: false,
981        }
982    }
983}
984
985/// A drop guard which can ensure the child process is killed on drop if specified.
986#[derive(Debug)]
987struct ChildDropGuard<T: Kill> {
988    inner: T,
989    kill_on_drop: bool,
990}
991
992impl<T: Kill> Kill for ChildDropGuard<T> {
993    fn kill(&mut self) -> io::Result<()> {
994        let ret = self.inner.kill();
995
996        if ret.is_ok() {
997            self.kill_on_drop = false;
998        }
999
1000        ret
1001    }
1002}
1003
1004impl<T: Kill> Drop for ChildDropGuard<T> {
1005    fn drop(&mut self) {
1006        if self.kill_on_drop {
1007            drop(self.kill());
1008        }
1009    }
1010}
1011
1012impl<T, E, F> Future for ChildDropGuard<F>
1013where
1014    F: Future<Output = Result<T, E>> + Kill + Unpin,
1015{
1016    type Output = Result<T, E>;
1017
1018    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1019        ready!(crate::trace::trace_leaf(cx));
1020        // Keep track of task budget
1021        let coop = ready!(crate::runtime::coop::poll_proceed(cx));
1022
1023        let ret = Pin::new(&mut self.inner).poll(cx);
1024
1025        if let Poll::Ready(Ok(_)) = ret {
1026            // Avoid the overhead of trying to kill a reaped process
1027            self.kill_on_drop = false;
1028        }
1029
1030        if ret.is_ready() {
1031            coop.made_progress();
1032        }
1033
1034        ret
1035    }
1036}
1037
1038/// Keeps track of the exit status of a child process without worrying about
1039/// polling the underlying futures even after they have completed.
1040#[derive(Debug)]
1041enum FusedChild {
1042    Child(ChildDropGuard<imp::Child>),
1043    Done(ExitStatus),
1044}
1045
1046/// Representation of a child process spawned onto an event loop.
1047///
1048/// # Caveats
1049/// Similar to the behavior to the standard library, and unlike the futures
1050/// paradigm of dropping-implies-cancellation, a spawned process will, by
1051/// default, continue to execute even after the `Child` handle has been dropped.
1052///
1053/// The `Command::kill_on_drop` method can be used to modify this behavior
1054/// and kill the child process if the `Child` wrapper is dropped before it
1055/// has exited.
1056#[derive(Debug)]
1057pub struct Child {
1058    child: FusedChild,
1059
1060    /// The handle for writing to the child's standard input (stdin), if it has
1061    /// been captured. To avoid partially moving the `child` and thus blocking
1062    /// yourself from calling functions on `child` while using `stdin`, you might
1063    /// find it helpful to do:
1064    ///
1065    /// ```no_run
1066    /// # let mut child = tokio::process::Command::new("echo").spawn().unwrap();
1067    /// let stdin = child.stdin.take().unwrap();
1068    /// ```
1069    pub stdin: Option<ChildStdin>,
1070
1071    /// The handle for reading from the child's standard output (stdout), if it
1072    /// has been captured. You might find it helpful to do
1073    ///
1074    /// ```no_run
1075    /// # let mut child = tokio::process::Command::new("echo").spawn().unwrap();
1076    /// let stdout = child.stdout.take().unwrap();
1077    /// ```
1078    ///
1079    /// to avoid partially moving the `child` and thus blocking yourself from calling
1080    /// functions on `child` while using `stdout`.
1081    pub stdout: Option<ChildStdout>,
1082
1083    /// The handle for reading from the child's standard error (stderr), if it
1084    /// has been captured. You might find it helpful to do
1085    ///
1086    /// ```no_run
1087    /// # let mut child = tokio::process::Command::new("echo").spawn().unwrap();
1088    /// let stderr = child.stderr.take().unwrap();
1089    /// ```
1090    ///
1091    /// to avoid partially moving the `child` and thus blocking yourself from calling
1092    /// functions on `child` while using `stderr`.
1093    pub stderr: Option<ChildStderr>,
1094}
1095
1096impl Child {
1097    /// Returns the OS-assigned process identifier associated with this child
1098    /// while it is still running.
1099    ///
1100    /// Once the child has been polled to completion this will return `None`.
1101    /// This is done to avoid confusion on platforms like Unix where the OS
1102    /// identifier could be reused once the process has completed.
1103    pub fn id(&self) -> Option<u32> {
1104        match &self.child {
1105            FusedChild::Child(child) => Some(child.inner.id()),
1106            FusedChild::Done(_) => None,
1107        }
1108    }
1109
1110    cfg_windows! {
1111        /// Extracts the raw handle of the process associated with this child while
1112        /// it is still running. Returns `None` if the child has exited.
1113        pub fn raw_handle(&self) -> Option<RawHandle> {
1114            match &self.child {
1115                FusedChild::Child(c) => Some(c.inner.as_raw_handle()),
1116                FusedChild::Done(_) => None,
1117            }
1118        }
1119    }
1120
1121    /// Attempts to force the child to exit, but does not wait for the request
1122    /// to take effect.
1123    ///
1124    /// On Unix platforms, this is the equivalent to sending a `SIGKILL`. Note
1125    /// that on Unix platforms it is possible for a zombie process to remain
1126    /// after a kill is sent; to avoid this, the caller should ensure that either
1127    /// `child.wait().await` or `child.try_wait()` is invoked successfully.
1128    pub fn start_kill(&mut self) -> io::Result<()> {
1129        match &mut self.child {
1130            FusedChild::Child(child) => child.kill(),
1131            FusedChild::Done(_) => Err(io::Error::new(
1132                io::ErrorKind::InvalidInput,
1133                "invalid argument: can't kill an exited process",
1134            )),
1135        }
1136    }
1137
1138    /// Forces the child to exit.
1139    ///
1140    /// This is equivalent to sending a `SIGKILL` on unix platforms.
1141    ///
1142    /// If the child has to be killed remotely, it is possible to do it using
1143    /// a combination of the select! macro and a `oneshot` channel. In the following
1144    /// example, the child will run until completion unless a message is sent on
1145    /// the `oneshot` channel. If that happens, the child is killed immediately
1146    /// using the `.kill()` method.
1147    ///
1148    /// ```no_run
1149    /// use tokio::process::Command;
1150    /// use tokio::sync::oneshot::channel;
1151    ///
1152    /// #[tokio::main]
1153    /// async fn main() {
1154    ///     let (send, recv) = channel::<()>();
1155    ///     let mut child = Command::new("sleep").arg("1").spawn().unwrap();
1156    ///     tokio::spawn(async move { send.send(()) });
1157    ///     tokio::select! {
1158    ///         _ = child.wait() => {}
1159    ///         _ = recv => child.kill().await.expect("kill failed"),
1160    ///     }
1161    /// }
1162    /// ```
1163    pub async fn kill(&mut self) -> io::Result<()> {
1164        self.start_kill()?;
1165        self.wait().await?;
1166        Ok(())
1167    }
1168
1169    /// Waits for the child to exit completely, returning the status that it
1170    /// exited with. This function will continue to have the same return value
1171    /// after it has been called at least once.
1172    ///
1173    /// The stdin handle to the child process, if any, will be closed
1174    /// before waiting. This helps avoid deadlock: it ensures that the
1175    /// child does not block waiting for input from the parent, while
1176    /// the parent waits for the child to exit.
1177    ///
1178    /// If the caller wishes to explicitly control when the child's stdin
1179    /// handle is closed, they may `.take()` it before calling `.wait()`:
1180    ///
1181    /// # Cancel safety
1182    ///
1183    /// This function is cancel safe.
1184    ///
1185    /// ```
1186    /// # #[cfg(not(unix))]fn main(){}
1187    /// # #[cfg(unix)]
1188    /// use tokio::io::AsyncWriteExt;
1189    /// # #[cfg(unix)]
1190    /// use tokio::process::Command;
1191    /// # #[cfg(unix)]
1192    /// use std::process::Stdio;
1193    ///
1194    /// # #[cfg(unix)]
1195    /// #[tokio::main]
1196    /// async fn main() {
1197    ///     let mut child = Command::new("cat")
1198    ///         .stdin(Stdio::piped())
1199    ///         .spawn()
1200    ///         .unwrap();
1201    ///
1202    ///     let mut stdin = child.stdin.take().unwrap();
1203    ///     tokio::spawn(async move {
1204    ///         // do something with stdin here...
1205    ///         stdin.write_all(b"hello world\n").await.unwrap();
1206    ///
1207    ///         // then drop when finished
1208    ///         drop(stdin);
1209    ///     });
1210    ///
1211    ///     // wait for the process to complete
1212    ///     let _ = child.wait().await;
1213    /// }
1214    /// ```
1215    pub async fn wait(&mut self) -> io::Result<ExitStatus> {
1216        // Ensure stdin is closed so the child isn't stuck waiting on
1217        // input while the parent is waiting for it to exit.
1218        drop(self.stdin.take());
1219
1220        match &mut self.child {
1221            FusedChild::Done(exit) => Ok(*exit),
1222            FusedChild::Child(child) => {
1223                let ret = child.await;
1224
1225                if let Ok(exit) = ret {
1226                    self.child = FusedChild::Done(exit);
1227                }
1228
1229                ret
1230            }
1231        }
1232    }
1233
1234    /// Attempts to collect the exit status of the child if it has already
1235    /// exited.
1236    ///
1237    /// This function will not block the calling thread and will only
1238    /// check to see if the child process has exited or not. If the child has
1239    /// exited then on Unix the process ID is reaped. This function is
1240    /// guaranteed to repeatedly return a successful exit status so long as the
1241    /// child has already exited.
1242    ///
1243    /// If the child has exited, then `Ok(Some(status))` is returned. If the
1244    /// exit status is not available at this time then `Ok(None)` is returned.
1245    /// If an error occurs, then that error is returned.
1246    ///
1247    /// Note that unlike `wait`, this function will not attempt to drop stdin,
1248    /// nor will it wake the current task if the child exits.
1249    pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
1250        match &mut self.child {
1251            FusedChild::Done(exit) => Ok(Some(*exit)),
1252            FusedChild::Child(guard) => {
1253                let ret = guard.inner.try_wait();
1254
1255                if let Ok(Some(exit)) = ret {
1256                    // Avoid the overhead of trying to kill a reaped process
1257                    guard.kill_on_drop = false;
1258                    self.child = FusedChild::Done(exit);
1259                }
1260
1261                ret
1262            }
1263        }
1264    }
1265
1266    /// Returns a future that will resolve to an `Output`, containing the exit
1267    /// status, stdout, and stderr of the child process.
1268    ///
1269    /// The returned future will simultaneously waits for the child to exit and
1270    /// collect all remaining output on the stdout/stderr handles, returning an
1271    /// `Output` instance.
1272    ///
1273    /// The stdin handle to the child process, if any, will be closed before
1274    /// waiting. This helps avoid deadlock: it ensures that the child does not
1275    /// block waiting for input from the parent, while the parent waits for the
1276    /// child to exit.
1277    ///
1278    /// By default, stdin, stdout and stderr are inherited from the parent. In
1279    /// order to capture the output into this `Output` it is necessary to create
1280    /// new pipes between parent and child. Use `stdout(Stdio::piped())` or
1281    /// `stderr(Stdio::piped())`, respectively, when creating a `Command`.
1282    pub async fn wait_with_output(mut self) -> io::Result<Output> {
1283        use crate::future::try_join3;
1284
1285        async fn read_to_end<A: AsyncRead + Unpin>(io: &mut Option<A>) -> io::Result<Vec<u8>> {
1286            let mut vec = Vec::new();
1287            if let Some(io) = io.as_mut() {
1288                crate::io::util::read_to_end(io, &mut vec).await?;
1289            }
1290            Ok(vec)
1291        }
1292
1293        let mut stdout_pipe = self.stdout.take();
1294        let mut stderr_pipe = self.stderr.take();
1295
1296        let stdout_fut = read_to_end(&mut stdout_pipe);
1297        let stderr_fut = read_to_end(&mut stderr_pipe);
1298
1299        let (status, stdout, stderr) = try_join3(self.wait(), stdout_fut, stderr_fut).await?;
1300
1301        // Drop happens after `try_join` due to <https://github.com/tokio-rs/tokio/issues/4309>
1302        drop(stdout_pipe);
1303        drop(stderr_pipe);
1304
1305        Ok(Output {
1306            status,
1307            stdout,
1308            stderr,
1309        })
1310    }
1311}
1312
1313/// The standard input stream for spawned children.
1314///
1315/// This type implements the `AsyncWrite` trait to pass data to the stdin handle of
1316/// handle of a child process asynchronously.
1317#[derive(Debug)]
1318pub struct ChildStdin {
1319    inner: imp::ChildStdio,
1320}
1321
1322/// The standard output stream for spawned children.
1323///
1324/// This type implements the `AsyncRead` trait to read data from the stdout
1325/// handle of a child process asynchronously.
1326#[derive(Debug)]
1327pub struct ChildStdout {
1328    inner: imp::ChildStdio,
1329}
1330
1331/// The standard error stream for spawned children.
1332///
1333/// This type implements the `AsyncRead` trait to read data from the stderr
1334/// handle of a child process asynchronously.
1335#[derive(Debug)]
1336pub struct ChildStderr {
1337    inner: imp::ChildStdio,
1338}
1339
1340impl ChildStdin {
1341    /// Creates an asynchronous `ChildStdin` from a synchronous one.
1342    ///
1343    /// # Errors
1344    ///
1345    /// This method may fail if an error is encountered when setting the pipe to
1346    /// non-blocking mode, or when registering the pipe with the runtime's IO
1347    /// driver.
1348    pub fn from_std(inner: std::process::ChildStdin) -> io::Result<Self> {
1349        Ok(Self {
1350            inner: imp::stdio(inner)?,
1351        })
1352    }
1353}
1354
1355impl ChildStdout {
1356    /// Creates an asynchronous `ChildStdout` from a synchronous one.
1357    ///
1358    /// # Errors
1359    ///
1360    /// This method may fail if an error is encountered when setting the pipe to
1361    /// non-blocking mode, or when registering the pipe with the runtime's IO
1362    /// driver.
1363    pub fn from_std(inner: std::process::ChildStdout) -> io::Result<Self> {
1364        Ok(Self {
1365            inner: imp::stdio(inner)?,
1366        })
1367    }
1368}
1369
1370impl ChildStderr {
1371    /// Creates an asynchronous `ChildStderr` from a synchronous one.
1372    ///
1373    /// # Errors
1374    ///
1375    /// This method may fail if an error is encountered when setting the pipe to
1376    /// non-blocking mode, or when registering the pipe with the runtime's IO
1377    /// driver.
1378    pub fn from_std(inner: std::process::ChildStderr) -> io::Result<Self> {
1379        Ok(Self {
1380            inner: imp::stdio(inner)?,
1381        })
1382    }
1383}
1384
1385impl AsyncWrite for ChildStdin {
1386    fn poll_write(
1387        mut self: Pin<&mut Self>,
1388        cx: &mut Context<'_>,
1389        buf: &[u8],
1390    ) -> Poll<io::Result<usize>> {
1391        Pin::new(&mut self.inner).poll_write(cx, buf)
1392    }
1393
1394    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1395        Pin::new(&mut self.inner).poll_flush(cx)
1396    }
1397
1398    fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1399        Pin::new(&mut self.inner).poll_shutdown(cx)
1400    }
1401
1402    fn poll_write_vectored(
1403        mut self: Pin<&mut Self>,
1404        cx: &mut Context<'_>,
1405        bufs: &[io::IoSlice<'_>],
1406    ) -> Poll<Result<usize, io::Error>> {
1407        Pin::new(&mut self.inner).poll_write_vectored(cx, bufs)
1408    }
1409
1410    fn is_write_vectored(&self) -> bool {
1411        self.inner.is_write_vectored()
1412    }
1413}
1414
1415impl AsyncRead for ChildStdout {
1416    fn poll_read(
1417        mut self: Pin<&mut Self>,
1418        cx: &mut Context<'_>,
1419        buf: &mut ReadBuf<'_>,
1420    ) -> Poll<io::Result<()>> {
1421        Pin::new(&mut self.inner).poll_read(cx, buf)
1422    }
1423}
1424
1425impl AsyncRead for ChildStderr {
1426    fn poll_read(
1427        mut self: Pin<&mut Self>,
1428        cx: &mut Context<'_>,
1429        buf: &mut ReadBuf<'_>,
1430    ) -> Poll<io::Result<()>> {
1431        Pin::new(&mut self.inner).poll_read(cx, buf)
1432    }
1433}
1434
1435impl TryInto<Stdio> for ChildStdin {
1436    type Error = io::Error;
1437
1438    fn try_into(self) -> Result<Stdio, Self::Error> {
1439        imp::convert_to_stdio(self.inner)
1440    }
1441}
1442
1443impl TryInto<Stdio> for ChildStdout {
1444    type Error = io::Error;
1445
1446    fn try_into(self) -> Result<Stdio, Self::Error> {
1447        imp::convert_to_stdio(self.inner)
1448    }
1449}
1450
1451impl TryInto<Stdio> for ChildStderr {
1452    type Error = io::Error;
1453
1454    fn try_into(self) -> Result<Stdio, Self::Error> {
1455        imp::convert_to_stdio(self.inner)
1456    }
1457}
1458
1459#[cfg(unix)]
1460#[cfg_attr(docsrs, doc(cfg(unix)))]
1461mod sys {
1462    use std::{
1463        io,
1464        os::unix::io::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd},
1465    };
1466
1467    use super::{ChildStderr, ChildStdin, ChildStdout};
1468
1469    macro_rules! impl_traits {
1470        ($type:ty) => {
1471            impl $type {
1472                /// Convert into [`OwnedFd`].
1473                pub fn into_owned_fd(self) -> io::Result<OwnedFd> {
1474                    self.inner.into_owned_fd()
1475                }
1476            }
1477
1478            impl AsRawFd for $type {
1479                fn as_raw_fd(&self) -> RawFd {
1480                    self.inner.as_raw_fd()
1481                }
1482            }
1483
1484            impl AsFd for $type {
1485                fn as_fd(&self) -> BorrowedFd<'_> {
1486                    unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
1487                }
1488            }
1489        };
1490    }
1491
1492    impl_traits!(ChildStdin);
1493    impl_traits!(ChildStdout);
1494    impl_traits!(ChildStderr);
1495}
1496
1497#[cfg(any(windows, docsrs))]
1498#[cfg_attr(docsrs, doc(cfg(windows)))]
1499mod windows {
1500    use super::*;
1501    use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, OwnedHandle, RawHandle};
1502
1503    #[cfg(not(docsrs))]
1504    macro_rules! impl_traits {
1505        ($type:ty) => {
1506            impl $type {
1507                /// Convert into [`OwnedHandle`].
1508                pub fn into_owned_handle(self) -> io::Result<OwnedHandle> {
1509                    self.inner.into_owned_handle()
1510                }
1511            }
1512
1513            impl AsRawHandle for $type {
1514                fn as_raw_handle(&self) -> RawHandle {
1515                    self.inner.as_raw_handle()
1516                }
1517            }
1518
1519            impl AsHandle for $type {
1520                fn as_handle(&self) -> BorrowedHandle<'_> {
1521                    unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
1522                }
1523            }
1524        };
1525    }
1526
1527    #[cfg(docsrs)]
1528    macro_rules! impl_traits {
1529        ($type:ty) => {
1530            impl $type {
1531                /// Convert into [`OwnedHandle`].
1532                pub fn into_owned_handle(self) -> io::Result<OwnedHandle> {
1533                    todo!("For doc generation only")
1534                }
1535            }
1536
1537            impl AsRawHandle for $type {
1538                fn as_raw_handle(&self) -> RawHandle {
1539                    todo!("For doc generation only")
1540                }
1541            }
1542
1543            impl AsHandle for $type {
1544                fn as_handle(&self) -> BorrowedHandle<'_> {
1545                    todo!("For doc generation only")
1546                }
1547            }
1548        };
1549    }
1550
1551    impl_traits!(ChildStdin);
1552    impl_traits!(ChildStdout);
1553    impl_traits!(ChildStderr);
1554}
1555
1556#[cfg(all(test, not(loom)))]
1557mod test {
1558    use super::kill::Kill;
1559    use super::ChildDropGuard;
1560
1561    use futures::future::FutureExt;
1562    use std::future::Future;
1563    use std::io;
1564    use std::pin::Pin;
1565    use std::task::{Context, Poll};
1566
1567    struct Mock {
1568        num_kills: usize,
1569        num_polls: usize,
1570        poll_result: Poll<Result<(), ()>>,
1571    }
1572
1573    impl Mock {
1574        fn new() -> Self {
1575            Self::with_result(Poll::Pending)
1576        }
1577
1578        fn with_result(result: Poll<Result<(), ()>>) -> Self {
1579            Self {
1580                num_kills: 0,
1581                num_polls: 0,
1582                poll_result: result,
1583            }
1584        }
1585    }
1586
1587    impl Kill for Mock {
1588        fn kill(&mut self) -> io::Result<()> {
1589            self.num_kills += 1;
1590            Ok(())
1591        }
1592    }
1593
1594    impl Future for Mock {
1595        type Output = Result<(), ()>;
1596
1597        fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
1598            let inner = Pin::get_mut(self);
1599            inner.num_polls += 1;
1600            inner.poll_result
1601        }
1602    }
1603
1604    #[test]
1605    fn kills_on_drop_if_specified() {
1606        let mut mock = Mock::new();
1607
1608        {
1609            let guard = ChildDropGuard {
1610                inner: &mut mock,
1611                kill_on_drop: true,
1612            };
1613            drop(guard);
1614        }
1615
1616        assert_eq!(1, mock.num_kills);
1617        assert_eq!(0, mock.num_polls);
1618    }
1619
1620    #[test]
1621    fn no_kill_on_drop_by_default() {
1622        let mut mock = Mock::new();
1623
1624        {
1625            let guard = ChildDropGuard {
1626                inner: &mut mock,
1627                kill_on_drop: false,
1628            };
1629            drop(guard);
1630        }
1631
1632        assert_eq!(0, mock.num_kills);
1633        assert_eq!(0, mock.num_polls);
1634    }
1635
1636    #[test]
1637    fn no_kill_if_already_killed() {
1638        let mut mock = Mock::new();
1639
1640        {
1641            let mut guard = ChildDropGuard {
1642                inner: &mut mock,
1643                kill_on_drop: true,
1644            };
1645            let _ = guard.kill();
1646            drop(guard);
1647        }
1648
1649        assert_eq!(1, mock.num_kills);
1650        assert_eq!(0, mock.num_polls);
1651    }
1652
1653    #[test]
1654    fn no_kill_if_reaped() {
1655        let mut mock_pending = Mock::with_result(Poll::Pending);
1656        let mut mock_reaped = Mock::with_result(Poll::Ready(Ok(())));
1657        let mut mock_err = Mock::with_result(Poll::Ready(Err(())));
1658
1659        let waker = futures::task::noop_waker();
1660        let mut context = Context::from_waker(&waker);
1661        {
1662            let mut guard = ChildDropGuard {
1663                inner: &mut mock_pending,
1664                kill_on_drop: true,
1665            };
1666            let _ = guard.poll_unpin(&mut context);
1667
1668            let mut guard = ChildDropGuard {
1669                inner: &mut mock_reaped,
1670                kill_on_drop: true,
1671            };
1672            let _ = guard.poll_unpin(&mut context);
1673
1674            let mut guard = ChildDropGuard {
1675                inner: &mut mock_err,
1676                kill_on_drop: true,
1677            };
1678            let _ = guard.poll_unpin(&mut context);
1679        }
1680
1681        assert_eq!(1, mock_pending.num_kills);
1682        assert_eq!(1, mock_pending.num_polls);
1683
1684        assert_eq!(0, mock_reaped.num_kills);
1685        assert_eq!(1, mock_reaped.num_polls);
1686
1687        assert_eq!(1, mock_err.num_kills);
1688        assert_eq!(1, mock_err.num_polls);
1689    }
1690}