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)]
231 mod imp;
232 
233 #[cfg(unix)]
234 pub(crate) mod unix {
235     pub(crate) use super::imp::*;
236 }
237 
238 #[path = "windows.rs"]
239 #[cfg(windows)]
240 mod imp;
241 
242 mod kill;
243 
244 use crate::io::{AsyncRead, AsyncWrite, ReadBuf};
245 use crate::process::kill::Kill;
246 
247 use std::ffi::OsStr;
248 use std::future::Future;
249 use std::io;
250 use std::path::Path;
251 use std::pin::Pin;
252 use std::process::{Command as StdCommand, ExitStatus, Output, Stdio};
253 use std::task::{ready, Context, Poll};
254 
255 #[cfg(unix)]
256 use std::os::unix::process::CommandExt;
257 #[cfg(windows)]
258 use std::os::windows::process::CommandExt;
259 
260 cfg_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)]
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 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
new<S: AsRef<OsStr>>(program: S) -> Command317     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.
as_std(&self) -> &StdCommand323     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.
as_std_mut(&mut self) -> &mut StdCommand329     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     /// ```
arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command373     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     /// ```
args<I, S>(&mut self, args: I) -> &mut Command where I: IntoIterator<Item = S>, S: AsRef<OsStr>,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     /// ```
env<K, V>(&mut self, key: K, val: V) -> &mut Command where K: AsRef<OsStr>, V: AsRef<OsStr>,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     /// ```
envs<I, K, V>(&mut self, vars: I) -> &mut Command where I: IntoIterator<Item = (K, V)>, K: AsRef<OsStr>, V: AsRef<OsStr>,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     /// ```
env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command495     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     /// ```
env_clear(&mut self) -> &mut Command515     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     /// ```
current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command545     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     /// ```
stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command570     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     /// ```
stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command597     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     /// ```
stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command624     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.
kill_on_drop(&mut self, kill_on_drop: bool) -> &mut Command655     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)))]
uid(&mut self, id: u32) -> &mut Command677     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)))]
gid(&mut self, id: u32) -> &mut Command688     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)))]
arg0<S>(&mut self, arg: S) -> &mut Command where S: AsRef<OsStr>,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)))]
pre_exec<F>(&mut self, f: F) -> &mut Command where F: FnMut() -> io::Result<()> + Send + Sync + 'static,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)))]
process_group(&mut self, pgroup: i32) -> &mut Command781     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).
spawn(&mut self) -> io::Result<Child>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     /// ```
status(&mut self) -> impl Future<Output = io::Result<ExitStatus>>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     /// ```
output(&mut self) -> impl Future<Output = io::Result<Output>>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 
976 impl From<StdCommand> for Command {
from(std: StdCommand) -> Command977     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)]
987 struct ChildDropGuard<T: Kill> {
988     inner: T,
989     kill_on_drop: bool,
990 }
991 
992 impl<T: Kill> Kill for ChildDropGuard<T> {
kill(&mut self) -> io::Result<()>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 
1004 impl<T: Kill> Drop for ChildDropGuard<T> {
drop(&mut self)1005     fn drop(&mut self) {
1006         if self.kill_on_drop {
1007             drop(self.kill());
1008         }
1009     }
1010 }
1011 
1012 impl<T, E, F> Future for ChildDropGuard<F>
1013 where
1014     F: Future<Output = Result<T, E>> + Kill + Unpin,
1015 {
1016     type Output = Result<T, E>;
1017 
poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>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)]
1041 enum 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)]
1057 pub 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 
1096 impl 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.
id(&self) -> Option<u32>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.
start_kill(&mut self) -> io::Result<()>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     /// ```
kill(&mut self) -> io::Result<()>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     /// ```
wait(&mut self) -> io::Result<ExitStatus>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.
try_wait(&mut self) -> io::Result<Option<ExitStatus>>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`.
wait_with_output(mut self) -> io::Result<Output>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)]
1318 pub 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)]
1327 pub 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)]
1336 pub struct ChildStderr {
1337     inner: imp::ChildStdio,
1338 }
1339 
1340 impl 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.
from_std(inner: std::process::ChildStdin) -> io::Result<Self>1348     pub fn from_std(inner: std::process::ChildStdin) -> io::Result<Self> {
1349         Ok(Self {
1350             inner: imp::stdio(inner)?,
1351         })
1352     }
1353 }
1354 
1355 impl 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.
from_std(inner: std::process::ChildStdout) -> io::Result<Self>1363     pub fn from_std(inner: std::process::ChildStdout) -> io::Result<Self> {
1364         Ok(Self {
1365             inner: imp::stdio(inner)?,
1366         })
1367     }
1368 }
1369 
1370 impl 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.
from_std(inner: std::process::ChildStderr) -> io::Result<Self>1378     pub fn from_std(inner: std::process::ChildStderr) -> io::Result<Self> {
1379         Ok(Self {
1380             inner: imp::stdio(inner)?,
1381         })
1382     }
1383 }
1384 
1385 impl AsyncWrite for ChildStdin {
poll_write( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<io::Result<usize>>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 
poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>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 
poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>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 
poll_write_vectored( mut self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[io::IoSlice<'_>], ) -> Poll<Result<usize, io::Error>>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 
is_write_vectored(&self) -> bool1410     fn is_write_vectored(&self) -> bool {
1411         self.inner.is_write_vectored()
1412     }
1413 }
1414 
1415 impl AsyncRead for ChildStdout {
poll_read( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<io::Result<()>>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 
1425 impl AsyncRead for ChildStderr {
poll_read( mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<io::Result<()>>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 
1435 impl TryInto<Stdio> for ChildStdin {
1436     type Error = io::Error;
1437 
try_into(self) -> Result<Stdio, Self::Error>1438     fn try_into(self) -> Result<Stdio, Self::Error> {
1439         imp::convert_to_stdio(self.inner)
1440     }
1441 }
1442 
1443 impl TryInto<Stdio> for ChildStdout {
1444     type Error = io::Error;
1445 
try_into(self) -> Result<Stdio, Self::Error>1446     fn try_into(self) -> Result<Stdio, Self::Error> {
1447         imp::convert_to_stdio(self.inner)
1448     }
1449 }
1450 
1451 impl TryInto<Stdio> for ChildStderr {
1452     type Error = io::Error;
1453 
try_into(self) -> Result<Stdio, Self::Error>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)))]
1461 mod 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)))]
1499 mod 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)))]
1557 mod 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 {
new() -> Self1574         fn new() -> Self {
1575             Self::with_result(Poll::Pending)
1576         }
1577 
with_result(result: Poll<Result<(), ()>>) -> Self1578         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 {
kill(&mut self) -> io::Result<()>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 
poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output>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]
kills_on_drop_if_specified()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]
no_kill_on_drop_by_default()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]
no_kill_if_already_killed()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]
no_kill_if_reaped()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 }
1691