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