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