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