Coverage Report

Created: 2026-02-14 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.44.2/src/process/mod.rs
Line
Count
Source
1
//! An implementation of asynchronous process management for Tokio.
2
//!
3
//! This module provides a [`Command`] struct that imitates the interface of the
4
//! [`std::process::Command`] type in the standard library, but provides asynchronous versions of
5
//! functions that create processes. These functions (`spawn`, `status`, `output` and their
6
//! variants) return "future aware" types that interoperate with Tokio. The asynchronous process
7
//! support is provided through signal handling on Unix and system APIs on Windows.
8
//!
9
//! [`std::process::Command`]: std::process::Command
10
//!
11
//! # Examples
12
//!
13
//! Here's an example program which will spawn `echo hello world` and then wait
14
//! for it complete.
15
//!
16
//! ```no_run
17
//! use tokio::process::Command;
18
//!
19
//! #[tokio::main]
20
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
21
//!     // The usage is similar as with the standard library's `Command` type
22
//!     let mut child = Command::new("echo")
23
//!         .arg("hello")
24
//!         .arg("world")
25
//!         .spawn()
26
//!         .expect("failed to spawn");
27
//!
28
//!     // Await until the command completes
29
//!     let status = child.wait().await?;
30
//!     println!("the command exited with: {}", status);
31
//!     Ok(())
32
//! }
33
//! ```
34
//!
35
//! Next, let's take a look at an example where we not only spawn `echo hello
36
//! world` but we also capture its output.
37
//!
38
//! ```no_run
39
//! use tokio::process::Command;
40
//!
41
//! #[tokio::main]
42
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
43
//!     // Like above, but use `output` which returns a future instead of
44
//!     // immediately returning the `Child`.
45
//!     let output = Command::new("echo").arg("hello").arg("world")
46
//!                         .output();
47
//!
48
//!     let output = output.await?;
49
//!
50
//!     assert!(output.status.success());
51
//!     assert_eq!(output.stdout, b"hello world\n");
52
//!     Ok(())
53
//! }
54
//! ```
55
//!
56
//! We can also read input line by line.
57
//!
58
//! ```no_run
59
//! use tokio::io::{BufReader, AsyncBufReadExt};
60
//! use tokio::process::Command;
61
//!
62
//! use std::process::Stdio;
63
//!
64
//! #[tokio::main]
65
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
66
//!     let mut cmd = Command::new("cat");
67
//!
68
//!     // Specify that we want the command's standard output piped back to us.
69
//!     // By default, standard input/output/error will be inherited from the
70
//!     // current process (for example, this means that standard input will
71
//!     // come from the keyboard and standard output/error will go directly to
72
//!     // the terminal if this process is invoked from the command line).
73
//!     cmd.stdout(Stdio::piped());
74
//!
75
//!     let mut child = cmd.spawn()
76
//!         .expect("failed to spawn command");
77
//!
78
//!     let stdout = child.stdout.take()
79
//!         .expect("child did not have a handle to stdout");
80
//!
81
//!     let mut reader = BufReader::new(stdout).lines();
82
//!
83
//!     // Ensure the child process is spawned in the runtime so it can
84
//!     // make progress on its own while we await for any output.
85
//!     tokio::spawn(async move {
86
//!         let status = child.wait().await
87
//!             .expect("child process encountered an error");
88
//!
89
//!         println!("child status was: {}", status);
90
//!     });
91
//!
92
//!     while let Some(line) = reader.next_line().await? {
93
//!         println!("Line: {}", line);
94
//!     }
95
//!
96
//!     Ok(())
97
//! }
98
//! ```
99
//!
100
//! Here is another example using `sort` writing into the child process
101
//! standard input, capturing the output of the sorted text.
102
//!
103
//! ```no_run
104
//! use tokio::io::AsyncWriteExt;
105
//! use tokio::process::Command;
106
//!
107
//! use std::process::Stdio;
108
//!
109
//! #[tokio::main]
110
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
111
//!     let mut cmd = Command::new("sort");
112
//!
113
//!     // Specifying that we want pipe both the output and the input.
114
//!     // Similarly to capturing the output, by configuring the pipe
115
//!     // to stdin it can now be used as an asynchronous writer.
116
//!     cmd.stdout(Stdio::piped());
117
//!     cmd.stdin(Stdio::piped());
118
//!
119
//!     let mut child = cmd.spawn().expect("failed to spawn command");
120
//!
121
//!     // These are the animals we want to sort
122
//!     let animals: &[&str] = &["dog", "bird", "frog", "cat", "fish"];
123
//!
124
//!     let mut stdin = child
125
//!         .stdin
126
//!         .take()
127
//!         .expect("child did not have a handle to stdin");
128
//!
129
//!     // Write our animals to the child process
130
//!     // Note that the behavior of `sort` is to buffer _all input_ before writing any output.
131
//!     // In the general sense, it is recommended to write to the child in a separate task as
132
//!     // awaiting its exit (or output) to avoid deadlocks (for example, the child tries to write
133
//!     // some output but gets stuck waiting on the parent to read from it, meanwhile the parent
134
//!     // is stuck waiting to write its input completely before reading the output).
135
//!     stdin
136
//!         .write(animals.join("\n").as_bytes())
137
//!         .await
138
//!         .expect("could not write to stdin");
139
//!
140
//!     // We drop the handle here which signals EOF to the child process.
141
//!     // This tells the child process that it there is no more data on the pipe.
142
//!     drop(stdin);
143
//!
144
//!     let op = child.wait_with_output().await?;
145
//!
146
//!     // Results should come back in sorted order
147
//!     assert_eq!(op.stdout, "bird\ncat\ndog\nfish\nfrog\n".as_bytes());
148
//!
149
//!     Ok(())
150
//! }
151
//! ```
152
//!
153
//! With some coordination, we can also pipe the output of one command into
154
//! another.
155
//!
156
//! ```no_run
157
//! use tokio::join;
158
//! use tokio::process::Command;
159
//! use std::process::Stdio;
160
//!
161
//! #[tokio::main]
162
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
163
//!     let mut echo = Command::new("echo")
164
//!         .arg("hello world!")
165
//!         .stdout(Stdio::piped())
166
//!         .spawn()
167
//!         .expect("failed to spawn echo");
168
//!
169
//!     let tr_stdin: Stdio = echo
170
//!         .stdout
171
//!         .take()
172
//!         .unwrap()
173
//!         .try_into()
174
//!         .expect("failed to convert to Stdio");
175
//!
176
//!     let tr = Command::new("tr")
177
//!         .arg("a-z")
178
//!         .arg("A-Z")
179
//!         .stdin(tr_stdin)
180
//!         .stdout(Stdio::piped())
181
//!         .spawn()
182
//!         .expect("failed to spawn tr");
183
//!
184
//!     let (echo_result, tr_output) = join!(echo.wait(), tr.wait_with_output());
185
//!
186
//!     assert!(echo_result.unwrap().success());
187
//!
188
//!     let tr_output = tr_output.expect("failed to await tr");
189
//!     assert!(tr_output.status.success());
190
//!
191
//!     assert_eq!(tr_output.stdout, b"HELLO WORLD!\n");
192
//!
193
//!     Ok(())
194
//! }
195
//! ```
196
//!
197
//! # Caveats
198
//!
199
//! ## Dropping/Cancellation
200
//!
201
//! Similar to the behavior to the standard library, and unlike the futures
202
//! paradigm of dropping-implies-cancellation, a spawned process will, by
203
//! default, continue to execute even after the `Child` handle has been dropped.
204
//!
205
//! The [`Command::kill_on_drop`] method can be used to modify this behavior
206
//! and kill the child process if the `Child` wrapper is dropped before it
207
//! has exited.
208
//!
209
//! ## Unix Processes
210
//!
211
//! On Unix platforms processes must be "reaped" by their parent process after
212
//! they have exited in order to release all OS resources. A child process which
213
//! has exited, but has not yet been reaped by its parent is considered a "zombie"
214
//! process. Such processes continue to count against limits imposed by the system,
215
//! and having too many zombie processes present can prevent additional processes
216
//! from being spawned.
217
//!
218
//! The tokio runtime will, on a best-effort basis, attempt to reap and clean up
219
//! any process which it has spawned. No additional guarantees are made with regard to
220
//! how quickly or how often this procedure will take place.
221
//!
222
//! It is recommended to avoid dropping a [`Child`] process handle before it has been
223
//! fully `await`ed if stricter cleanup guarantees are required.
224
//!
225
//! [`Command`]: crate::process::Command
226
//! [`Command::kill_on_drop`]: crate::process::Command::kill_on_drop
227
//! [`Child`]: crate::process::Child
228
229
#[path = "unix/mod.rs"]
230
#[cfg(unix)]
231
mod imp;
232
233
#[cfg(unix)]
234
pub(crate) mod unix {
235
    pub(crate) use super::imp::*;
236
}
237
238
#[path = "windows.rs"]
239
#[cfg(windows)]
240
mod imp;
241
242
mod kill;
243
244
use crate::io::{AsyncRead, AsyncWrite, ReadBuf};
245
use crate::process::kill::Kill;
246
247
use std::ffi::OsStr;
248
use std::future::Future;
249
use std::io;
250
use std::path::Path;
251
use std::pin::Pin;
252
use std::process::{Command as StdCommand, ExitStatus, Output, Stdio};
253
use std::task::{ready, Context, Poll};
254
255
#[cfg(unix)]
256
use std::os::unix::process::CommandExt;
257
#[cfg(windows)]
258
use std::os::windows::process::CommandExt;
259
260
cfg_windows! {
261
    use crate::os::windows::io::{AsRawHandle, RawHandle};
262
}
263
264
/// This structure mimics the API of [`std::process::Command`] found in the standard library, but
265
/// replaces functions that create a process with an asynchronous variant. The main provided
266
/// asynchronous functions are [spawn](Command::spawn), [status](Command::status), and
267
/// [output](Command::output).
268
///
269
/// `Command` uses asynchronous versions of some `std` types (for example [`Child`]).
270
///
271
/// [`std::process::Command`]: std::process::Command
272
/// [`Child`]: struct@Child
273
#[derive(Debug)]
274
pub struct Command {
275
    std: StdCommand,
276
    kill_on_drop: bool,
277
}
278
279
pub(crate) struct SpawnedChild {
280
    child: imp::Child,
281
    stdin: Option<imp::ChildStdio>,
282
    stdout: Option<imp::ChildStdio>,
283
    stderr: Option<imp::ChildStdio>,
284
}
285
286
impl Command {
287
    /// Constructs a new `Command` for launching the program at
288
    /// path `program`, with the following default configuration:
289
    ///
290
    /// * No arguments to the program
291
    /// * Inherit the current process's environment
292
    /// * Inherit the current process's working directory
293
    /// * Inherit stdin/stdout/stderr for `spawn` or `status`, but create pipes for `output`
294
    ///
295
    /// Builder methods are provided to change these defaults and
296
    /// otherwise configure the process.
297
    ///
298
    /// If `program` is not an absolute path, the `PATH` will be searched in
299
    /// an OS-defined way.
300
    ///
301
    /// The search path to be used may be controlled by setting the
302
    /// `PATH` environment variable on the Command,
303
    /// but this has some implementation limitations on Windows
304
    /// (see issue [rust-lang/rust#37519]).
305
    ///
306
    /// # Examples
307
    ///
308
    /// Basic usage:
309
    ///
310
    /// ```no_run
311
    /// use tokio::process::Command;
312
    /// let mut command = Command::new("sh");
313
    /// # let _ = command.output(); // assert borrow checker
314
    /// ```
315
    ///
316
    /// [rust-lang/rust#37519]: https://github.com/rust-lang/rust/issues/37519
317
0
    pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
318
0
        Self::from(StdCommand::new(program))
319
0
    }
320
321
    /// Cheaply convert to a `&std::process::Command` for places where the type from the standard
322
    /// library is expected.
323
0
    pub fn as_std(&self) -> &StdCommand {
324
0
        &self.std
325
0
    }
326
327
    /// Cheaply convert to a `&mut std::process::Command` for places where the type from the
328
    /// standard library is expected.
329
0
    pub fn as_std_mut(&mut self) -> &mut StdCommand {
330
0
        &mut self.std
331
0
    }
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
0
    pub fn into_std(self) -> StdCommand {
339
0
        self.std
340
0
    }
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
0
    pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {
383
0
        self.std.arg(arg);
384
0
        self
385
0
    }
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
0
    pub fn args<I, S>(&mut self, args: I) -> &mut Command
407
0
    where
408
0
        I: IntoIterator<Item = S>,
409
0
        S: AsRef<OsStr>,
410
    {
411
0
        self.std.args(args);
412
0
        self
413
0
    }
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
0
    pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
445
0
    where
446
0
        K: AsRef<OsStr>,
447
0
        V: AsRef<OsStr>,
448
    {
449
0
        self.std.env(key, val);
450
0
        self
451
0
    }
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
0
    pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command
480
0
    where
481
0
        I: IntoIterator<Item = (K, V)>,
482
0
        K: AsRef<OsStr>,
483
0
        V: AsRef<OsStr>,
484
    {
485
0
        self.std.envs(vars);
486
0
        self
487
0
    }
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
0
    pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
505
0
        self.std.env_remove(key);
506
0
        self
507
0
    }
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
0
    pub fn env_clear(&mut self) -> &mut Command {
525
0
        self.std.env_clear();
526
0
        self
527
0
    }
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
0
    pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command {
555
0
        self.std.current_dir(dir);
556
0
        self
557
0
    }
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
0
    pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
580
0
        self.std.stdin(cfg);
581
0
        self
582
0
    }
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
0
    pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
607
0
        self.std.stdout(cfg);
608
0
        self
609
0
    }
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
0
    pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
634
0
        self.std.stderr(cfg);
635
0
        self
636
0
    }
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
0
    pub fn kill_on_drop(&mut self, kill_on_drop: bool) -> &mut Command {
665
0
        self.kill_on_drop = kill_on_drop;
666
0
        self
667
0
    }
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
0
    pub fn uid(&mut self, id: u32) -> &mut Command {
687
        #[cfg(target_os = "nto")]
688
        let id = id as i32;
689
0
        self.std.uid(id);
690
0
        self
691
0
    }
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
0
    pub fn gid(&mut self, id: u32) -> &mut Command {
698
        #[cfg(target_os = "nto")]
699
        let id = id as i32;
700
0
        self.std.gid(id);
701
0
        self
702
0
    }
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
0
    pub fn arg0<S>(&mut self, arg: S) -> &mut Command
711
0
    where
712
0
        S: AsRef<OsStr>,
713
    {
714
0
        self.std.arg0(arg);
715
0
        self
716
0
    }
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
0
    pub unsafe fn pre_exec<F>(&mut self, f: F) -> &mut Command
750
0
    where
751
0
        F: FnMut() -> io::Result<()> + Send + Sync + 'static,
752
    {
753
0
        self.std.pre_exec(f);
754
0
        self
755
0
    }
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
0
    pub fn process_group(&mut self, pgroup: i32) -> &mut Command {
791
0
        self.std.process_group(pgroup);
792
0
        self
793
0
    }
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
    /// # if cfg!(miri) { return } // No `pidfd_spawnp` in miri.
814
    /// use tokio::process::Command;
815
    ///
816
    /// async fn run_ls() -> std::process::ExitStatus {
817
    ///     Command::new("ls")
818
    ///         .spawn()
819
    ///         .expect("ls command failed to start")
820
    ///         .wait()
821
    ///         .await
822
    ///         .expect("ls command failed to run")
823
    /// }
824
    /// ```
825
    ///
826
    /// # Caveats
827
    ///
828
    /// ## Dropping/Cancellation
829
    ///
830
    /// Similar to the behavior to the standard library, and unlike the futures
831
    /// paradigm of dropping-implies-cancellation, a spawned process will, by
832
    /// default, continue to execute even after the `Child` handle has been dropped.
833
    ///
834
    /// The [`Command::kill_on_drop`] method can be used to modify this behavior
835
    /// and kill the child process if the `Child` wrapper is dropped before it
836
    /// has exited.
837
    ///
838
    /// ## Unix Processes
839
    ///
840
    /// On Unix platforms processes must be "reaped" by their parent process after
841
    /// they have exited in order to release all OS resources. A child process which
842
    /// has exited, but has not yet been reaped by its parent is considered a "zombie"
843
    /// process. Such processes continue to count against limits imposed by the system,
844
    /// and having too many zombie processes present can prevent additional processes
845
    /// from being spawned.
846
    ///
847
    /// The tokio runtime will, on a best-effort basis, attempt to reap and clean up
848
    /// any process which it has spawned. No additional guarantees are made with regard to
849
    /// how quickly or how often this procedure will take place.
850
    ///
851
    /// It is recommended to avoid dropping a [`Child`] process handle before it has been
852
    /// fully `await`ed if stricter cleanup guarantees are required.
853
    ///
854
    /// [`Command`]: crate::process::Command
855
    /// [`Command::kill_on_drop`]: crate::process::Command::kill_on_drop
856
    /// [`Child`]: crate::process::Child
857
    ///
858
    /// # Errors
859
    ///
860
    /// On Unix platforms this method will fail with `std::io::ErrorKind::WouldBlock`
861
    /// if the system process limit is reached (which includes other applications
862
    /// running on the system).
863
0
    pub fn spawn(&mut self) -> io::Result<Child> {
864
0
        imp::spawn_child(&mut self.std).map(|spawned_child| Child {
865
0
            child: FusedChild::Child(ChildDropGuard {
866
0
                inner: spawned_child.child,
867
0
                kill_on_drop: self.kill_on_drop,
868
0
            }),
869
0
            stdin: spawned_child.stdin.map(|inner| ChildStdin { inner }),
870
0
            stdout: spawned_child.stdout.map(|inner| ChildStdout { inner }),
871
0
            stderr: spawned_child.stderr.map(|inner| ChildStderr { inner }),
872
0
        })
873
0
    }
874
875
    /// Executes the command as a child process, waiting for it to finish and
876
    /// collecting its exit status.
877
    ///
878
    /// By default, stdin, stdout and stderr are inherited from the parent.
879
    /// If any input/output handles are set to a pipe then they will be immediately
880
    /// closed after the child is spawned.
881
    ///
882
    /// All I/O this child does will be associated with the current default
883
    /// event loop.
884
    ///
885
    /// The destructor of the future returned by this function will kill
886
    /// the child if [`kill_on_drop`] is set to true.
887
    ///
888
    /// [`kill_on_drop`]: fn@Self::kill_on_drop
889
    ///
890
    /// # Errors
891
    ///
892
    /// This future will return an error if the child process cannot be spawned
893
    /// or if there is an error while awaiting its status.
894
    ///
895
    /// On Unix platforms this method will fail with `std::io::ErrorKind::WouldBlock`
896
    /// if the system process limit is reached (which includes other applications
897
    /// running on the system).
898
    ///
899
    /// # Examples
900
    ///
901
    /// Basic usage:
902
    ///
903
    /// ```no_run
904
    /// use tokio::process::Command;
905
    ///
906
    /// async fn run_ls() -> std::process::ExitStatus {
907
    ///     Command::new("ls")
908
    ///         .status()
909
    ///         .await
910
    ///         .expect("ls command failed to run")
911
    /// }
912
    /// ```
913
0
    pub fn status(&mut self) -> impl Future<Output = io::Result<ExitStatus>> {
914
0
        let child = self.spawn();
915
916
0
        async {
917
0
            let mut child = child?;
918
919
            // Ensure we close any stdio handles so we can't deadlock
920
            // waiting on the child which may be waiting to read/write
921
            // to a pipe we're holding.
922
0
            child.stdin.take();
923
0
            child.stdout.take();
924
0
            child.stderr.take();
925
926
0
            child.wait().await
927
0
        }
928
0
    }
929
930
    /// Executes the command as a child process, waiting for it to finish and
931
    /// collecting all of its output.
932
    ///
933
    /// > **Note**: this method, unlike the standard library, will
934
    /// > unconditionally configure the stdout/stderr handles to be pipes, even
935
    /// > if they have been previously configured. If this is not desired then
936
    /// > the `spawn` method should be used in combination with the
937
    /// > `wait_with_output` method on child.
938
    ///
939
    /// This method will return a future representing the collection of the
940
    /// child process's stdout/stderr. It will resolve to
941
    /// the `Output` type in the standard library, containing `stdout` and
942
    /// `stderr` as `Vec<u8>` along with an `ExitStatus` representing how the
943
    /// process exited.
944
    ///
945
    /// All I/O this child does will be associated with the current default
946
    /// event loop.
947
    ///
948
    /// The destructor of the future returned by this function will kill
949
    /// the child if [`kill_on_drop`] is set to true.
950
    ///
951
    /// [`kill_on_drop`]: fn@Self::kill_on_drop
952
    ///
953
    /// # Errors
954
    ///
955
    /// This future will return an error if the child process cannot be spawned
956
    /// or if there is an error while awaiting its status.
957
    ///
958
    /// On Unix platforms this method will fail with `std::io::ErrorKind::WouldBlock`
959
    /// if the system process limit is reached (which includes other applications
960
    /// running on the system).
961
    /// # Examples
962
    ///
963
    /// Basic usage:
964
    ///
965
    /// ```no_run
966
    /// use tokio::process::Command;
967
    ///
968
    /// async fn run_ls() {
969
    ///     let output: std::process::Output = Command::new("ls")
970
    ///         .output()
971
    ///         .await
972
    ///         .expect("ls command failed to run");
973
    ///     println!("stderr of ls: {:?}", output.stderr);
974
    /// }
975
    /// ```
976
0
    pub fn output(&mut self) -> impl Future<Output = io::Result<Output>> {
977
0
        self.std.stdout(Stdio::piped());
978
0
        self.std.stderr(Stdio::piped());
979
980
0
        let child = self.spawn();
981
982
0
        async { child?.wait_with_output().await }
983
0
    }
984
985
    /// Returns the boolean value that was previously set by [`Command::kill_on_drop`].
986
    ///
987
    /// Note that if you have not previously called [`Command::kill_on_drop`], the
988
    /// default value of `false` will be returned here.
989
    ///
990
    /// # Examples
991
    ///
992
    /// ```
993
    /// use tokio::process::Command;
994
    ///
995
    /// let mut cmd = Command::new("echo");
996
    /// assert!(!cmd.get_kill_on_drop());
997
    ///
998
    /// cmd.kill_on_drop(true);
999
    /// assert!(cmd.get_kill_on_drop());
1000
    /// ```
1001
0
    pub fn get_kill_on_drop(&self) -> bool {
1002
0
        self.kill_on_drop
1003
0
    }
1004
}
1005
1006
impl From<StdCommand> for Command {
1007
0
    fn from(std: StdCommand) -> Command {
1008
0
        Command {
1009
0
            std,
1010
0
            kill_on_drop: false,
1011
0
        }
1012
0
    }
1013
}
1014
1015
/// A drop guard which can ensure the child process is killed on drop if specified.
1016
#[derive(Debug)]
1017
struct ChildDropGuard<T: Kill> {
1018
    inner: T,
1019
    kill_on_drop: bool,
1020
}
1021
1022
impl<T: Kill> Kill for ChildDropGuard<T> {
1023
0
    fn kill(&mut self) -> io::Result<()> {
1024
0
        let ret = self.inner.kill();
1025
1026
0
        if ret.is_ok() {
1027
0
            self.kill_on_drop = false;
1028
0
        }
1029
1030
0
        ret
1031
0
    }
1032
}
1033
1034
impl<T: Kill> Drop for ChildDropGuard<T> {
1035
0
    fn drop(&mut self) {
1036
0
        if self.kill_on_drop {
1037
0
            drop(self.kill());
1038
0
        }
1039
0
    }
1040
}
1041
1042
impl<T, E, F> Future for ChildDropGuard<F>
1043
where
1044
    F: Future<Output = Result<T, E>> + Kill + Unpin,
1045
{
1046
    type Output = Result<T, E>;
1047
1048
0
    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1049
0
        ready!(crate::trace::trace_leaf(cx));
1050
        // Keep track of task budget
1051
0
        let coop = ready!(crate::task::coop::poll_proceed(cx));
1052
1053
0
        let ret = Pin::new(&mut self.inner).poll(cx);
1054
1055
0
        if let Poll::Ready(Ok(_)) = ret {
1056
0
            // Avoid the overhead of trying to kill a reaped process
1057
0
            self.kill_on_drop = false;
1058
0
        }
1059
1060
0
        if ret.is_ready() {
1061
0
            coop.made_progress();
1062
0
        }
1063
1064
0
        ret
1065
0
    }
1066
}
1067
1068
/// Keeps track of the exit status of a child process without worrying about
1069
/// polling the underlying futures even after they have completed.
1070
#[derive(Debug)]
1071
enum FusedChild {
1072
    Child(ChildDropGuard<imp::Child>),
1073
    Done(ExitStatus),
1074
}
1075
1076
/// Representation of a child process spawned onto an event loop.
1077
///
1078
/// # Caveats
1079
/// Similar to the behavior to the standard library, and unlike the futures
1080
/// paradigm of dropping-implies-cancellation, a spawned process will, by
1081
/// default, continue to execute even after the `Child` handle has been dropped.
1082
///
1083
/// The `Command::kill_on_drop` method can be used to modify this behavior
1084
/// and kill the child process if the `Child` wrapper is dropped before it
1085
/// has exited.
1086
#[derive(Debug)]
1087
pub struct Child {
1088
    child: FusedChild,
1089
1090
    /// The handle for writing to the child's standard input (stdin), if it has
1091
    /// been captured. To avoid partially moving the `child` and thus blocking
1092
    /// yourself from calling functions on `child` while using `stdin`, you might
1093
    /// find it helpful to do:
1094
    ///
1095
    /// ```no_run
1096
    /// # let mut child = tokio::process::Command::new("echo").spawn().unwrap();
1097
    /// let stdin = child.stdin.take().unwrap();
1098
    /// ```
1099
    pub stdin: Option<ChildStdin>,
1100
1101
    /// The handle for reading from the child's standard output (stdout), if it
1102
    /// has been captured. You might find it helpful to do
1103
    ///
1104
    /// ```no_run
1105
    /// # let mut child = tokio::process::Command::new("echo").spawn().unwrap();
1106
    /// let stdout = child.stdout.take().unwrap();
1107
    /// ```
1108
    ///
1109
    /// to avoid partially moving the `child` and thus blocking yourself from calling
1110
    /// functions on `child` while using `stdout`.
1111
    pub stdout: Option<ChildStdout>,
1112
1113
    /// The handle for reading from the child's standard error (stderr), if it
1114
    /// has been captured. You might find it helpful to do
1115
    ///
1116
    /// ```no_run
1117
    /// # let mut child = tokio::process::Command::new("echo").spawn().unwrap();
1118
    /// let stderr = child.stderr.take().unwrap();
1119
    /// ```
1120
    ///
1121
    /// to avoid partially moving the `child` and thus blocking yourself from calling
1122
    /// functions on `child` while using `stderr`.
1123
    pub stderr: Option<ChildStderr>,
1124
}
1125
1126
impl Child {
1127
    /// Returns the OS-assigned process identifier associated with this child
1128
    /// while it is still running.
1129
    ///
1130
    /// Once the child has been polled to completion this will return `None`.
1131
    /// This is done to avoid confusion on platforms like Unix where the OS
1132
    /// identifier could be reused once the process has completed.
1133
0
    pub fn id(&self) -> Option<u32> {
1134
0
        match &self.child {
1135
0
            FusedChild::Child(child) => Some(child.inner.id()),
1136
0
            FusedChild::Done(_) => None,
1137
        }
1138
0
    }
1139
1140
    cfg_windows! {
1141
        /// Extracts the raw handle of the process associated with this child while
1142
        /// it is still running. Returns `None` if the child has exited.
1143
        pub fn raw_handle(&self) -> Option<RawHandle> {
1144
            match &self.child {
1145
                FusedChild::Child(c) => Some(c.inner.as_raw_handle()),
1146
                FusedChild::Done(_) => None,
1147
            }
1148
        }
1149
    }
1150
1151
    /// Attempts to force the child to exit, but does not wait for the request
1152
    /// to take effect.
1153
    ///
1154
    /// On Unix platforms, this is the equivalent to sending a `SIGKILL`. Note
1155
    /// that on Unix platforms it is possible for a zombie process to remain
1156
    /// after a kill is sent; to avoid this, the caller should ensure that either
1157
    /// `child.wait().await` or `child.try_wait()` is invoked successfully.
1158
0
    pub fn start_kill(&mut self) -> io::Result<()> {
1159
0
        match &mut self.child {
1160
0
            FusedChild::Child(child) => child.kill(),
1161
0
            FusedChild::Done(_) => Ok(()),
1162
        }
1163
0
    }
1164
1165
    /// Forces the child to exit.
1166
    ///
1167
    /// This is equivalent to sending a `SIGKILL` on unix platforms
1168
    /// followed by [`wait`](Child::wait).
1169
    ///
1170
    /// Note: std version of [`Child::kill`](std::process::Child::kill) does not `wait`.
1171
    /// For an equivalent of `Child::kill` in the standard library,
1172
    /// use [`start_kill`](Child::start_kill).
1173
    ///
1174
    /// # Examples
1175
    ///
1176
    /// If the child has to be killed remotely, it is possible to do it using
1177
    /// a combination of the select! macro and a `oneshot` channel. In the following
1178
    /// example, the child will run until completion unless a message is sent on
1179
    /// the `oneshot` channel. If that happens, the child is killed immediately
1180
    /// using the `.kill()` method.
1181
    ///
1182
    /// ```no_run
1183
    /// use tokio::process::Command;
1184
    /// use tokio::sync::oneshot::channel;
1185
    ///
1186
    /// #[tokio::main]
1187
    /// async fn main() {
1188
    ///     let (send, recv) = channel::<()>();
1189
    ///     let mut child = Command::new("sleep").arg("1").spawn().unwrap();
1190
    ///     tokio::spawn(async move { send.send(()) });
1191
    ///     tokio::select! {
1192
    ///         _ = child.wait() => {}
1193
    ///         _ = recv => child.kill().await.expect("kill failed"),
1194
    ///     }
1195
    /// }
1196
    /// ```
1197
    ///
1198
    /// You can also interact with the child's standard I/O. For example, you can
1199
    /// read its stdout while waiting for it to exit.
1200
    ///
1201
    /// ```no_run
1202
    /// # use std::process::Stdio;
1203
    /// #
1204
    /// # use tokio::io::AsyncReadExt;
1205
    /// # use tokio::process::Command;
1206
    /// # use tokio::sync::oneshot::channel;
1207
    ///
1208
    /// #[tokio::main]
1209
    /// async fn main() {
1210
    ///     let (_tx, rx) = channel::<()>();
1211
    ///
1212
    ///     let mut child = Command::new("echo")
1213
    ///         .arg("Hello World!")
1214
    ///         .stdout(Stdio::piped())
1215
    ///         .spawn()
1216
    ///         .unwrap();
1217
    ///
1218
    ///     let mut stdout = child.stdout.take().expect("stdout is not captured");
1219
    ///
1220
    ///     let read_stdout = tokio::spawn(async move {
1221
    ///         let mut buff = Vec::new();
1222
    ///         let _ = stdout.read_to_end(&mut buff).await;
1223
    ///
1224
    ///         buff
1225
    ///     });
1226
    ///
1227
    ///     tokio::select! {
1228
    ///         _ = child.wait() => {}
1229
    ///         _ = rx => { child.kill().await.expect("kill failed") },
1230
    ///     }
1231
    ///
1232
    ///     let buff = read_stdout.await.unwrap();
1233
    ///
1234
    ///     assert_eq!(buff, b"Hello World!\n");
1235
    /// }
1236
    /// ```
1237
0
    pub async fn kill(&mut self) -> io::Result<()> {
1238
0
        self.start_kill()?;
1239
0
        self.wait().await?;
1240
0
        Ok(())
1241
0
    }
1242
1243
    /// Waits for the child to exit completely, returning the status that it
1244
    /// exited with. This function will continue to have the same return value
1245
    /// after it has been called at least once.
1246
    ///
1247
    /// The stdin handle to the child process, if any, will be closed
1248
    /// before waiting. This helps avoid deadlock: it ensures that the
1249
    /// child does not block waiting for input from the parent, while
1250
    /// the parent waits for the child to exit.
1251
    ///
1252
    /// If the caller wishes to explicitly control when the child's stdin
1253
    /// handle is closed, they may `.take()` it before calling `.wait()`:
1254
    ///
1255
    /// # Cancel safety
1256
    ///
1257
    /// This function is cancel safe.
1258
    ///
1259
    /// ```
1260
    /// # if cfg!(miri) { return } // No `pidfd_spawnp` in miri.
1261
    /// # #[cfg(not(unix))]fn main(){}
1262
    /// # #[cfg(unix)]
1263
    /// use tokio::io::AsyncWriteExt;
1264
    /// # #[cfg(unix)]
1265
    /// use tokio::process::Command;
1266
    /// # #[cfg(unix)]
1267
    /// use std::process::Stdio;
1268
    ///
1269
    /// # #[cfg(unix)]
1270
    /// #[tokio::main]
1271
    /// async fn main() {
1272
    ///     let mut child = Command::new("cat")
1273
    ///         .stdin(Stdio::piped())
1274
    ///         .spawn()
1275
    ///         .unwrap();
1276
    ///
1277
    ///     let mut stdin = child.stdin.take().unwrap();
1278
    ///     tokio::spawn(async move {
1279
    ///         // do something with stdin here...
1280
    ///         stdin.write_all(b"hello world\n").await.unwrap();
1281
    ///
1282
    ///         // then drop when finished
1283
    ///         drop(stdin);
1284
    ///     });
1285
    ///
1286
    ///     // wait for the process to complete
1287
    ///     let _ = child.wait().await;
1288
    /// }
1289
    /// ```
1290
0
    pub async fn wait(&mut self) -> io::Result<ExitStatus> {
1291
        // Ensure stdin is closed so the child isn't stuck waiting on
1292
        // input while the parent is waiting for it to exit.
1293
0
        drop(self.stdin.take());
1294
1295
0
        match &mut self.child {
1296
0
            FusedChild::Done(exit) => Ok(*exit),
1297
0
            FusedChild::Child(child) => {
1298
0
                let ret = child.await;
1299
1300
0
                if let Ok(exit) = ret {
1301
0
                    self.child = FusedChild::Done(exit);
1302
0
                }
1303
1304
0
                ret
1305
            }
1306
        }
1307
0
    }
1308
1309
    /// Attempts to collect the exit status of the child if it has already
1310
    /// exited.
1311
    ///
1312
    /// This function will not block the calling thread and will only
1313
    /// check to see if the child process has exited or not. If the child has
1314
    /// exited then on Unix the process ID is reaped. This function is
1315
    /// guaranteed to repeatedly return a successful exit status so long as the
1316
    /// child has already exited.
1317
    ///
1318
    /// If the child has exited, then `Ok(Some(status))` is returned. If the
1319
    /// exit status is not available at this time then `Ok(None)` is returned.
1320
    /// If an error occurs, then that error is returned.
1321
    ///
1322
    /// Note that unlike `wait`, this function will not attempt to drop stdin,
1323
    /// nor will it wake the current task if the child exits.
1324
0
    pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
1325
0
        match &mut self.child {
1326
0
            FusedChild::Done(exit) => Ok(Some(*exit)),
1327
0
            FusedChild::Child(guard) => {
1328
0
                let ret = guard.inner.try_wait();
1329
1330
0
                if let Ok(Some(exit)) = ret {
1331
0
                    // Avoid the overhead of trying to kill a reaped process
1332
0
                    guard.kill_on_drop = false;
1333
0
                    self.child = FusedChild::Done(exit);
1334
0
                }
1335
1336
0
                ret
1337
            }
1338
        }
1339
0
    }
1340
1341
    /// Returns a future that will resolve to an `Output`, containing the exit
1342
    /// status, stdout, and stderr of the child process.
1343
    ///
1344
    /// The returned future will simultaneously waits for the child to exit and
1345
    /// collect all remaining output on the stdout/stderr handles, returning an
1346
    /// `Output` instance.
1347
    ///
1348
    /// The stdin handle to the child process, if any, will be closed before
1349
    /// waiting. This helps avoid deadlock: it ensures that the child does not
1350
    /// block waiting for input from the parent, while the parent waits for the
1351
    /// child to exit.
1352
    ///
1353
    /// By default, stdin, stdout and stderr are inherited from the parent. In
1354
    /// order to capture the output into this `Output` it is necessary to create
1355
    /// new pipes between parent and child. Use `stdout(Stdio::piped())` or
1356
    /// `stderr(Stdio::piped())`, respectively, when creating a `Command`.
1357
0
    pub async fn wait_with_output(mut self) -> io::Result<Output> {
1358
        use crate::future::try_join3;
1359
1360
0
        async fn read_to_end<A: AsyncRead + Unpin>(io: &mut Option<A>) -> io::Result<Vec<u8>> {
1361
0
            let mut vec = Vec::new();
1362
0
            if let Some(io) = io.as_mut() {
1363
0
                crate::io::util::read_to_end(io, &mut vec).await?;
1364
0
            }
1365
0
            Ok(vec)
1366
0
        }
1367
1368
0
        let mut stdout_pipe = self.stdout.take();
1369
0
        let mut stderr_pipe = self.stderr.take();
1370
1371
0
        let stdout_fut = read_to_end(&mut stdout_pipe);
1372
0
        let stderr_fut = read_to_end(&mut stderr_pipe);
1373
1374
0
        let (status, stdout, stderr) = try_join3(self.wait(), stdout_fut, stderr_fut).await?;
1375
1376
        // Drop happens after `try_join` due to <https://github.com/tokio-rs/tokio/issues/4309>
1377
0
        drop(stdout_pipe);
1378
0
        drop(stderr_pipe);
1379
1380
0
        Ok(Output {
1381
0
            status,
1382
0
            stdout,
1383
0
            stderr,
1384
0
        })
1385
0
    }
1386
}
1387
1388
/// The standard input stream for spawned children.
1389
///
1390
/// This type implements the `AsyncWrite` trait to pass data to the stdin
1391
/// handle of a child process asynchronously.
1392
#[derive(Debug)]
1393
pub struct ChildStdin {
1394
    inner: imp::ChildStdio,
1395
}
1396
1397
/// The standard output stream for spawned children.
1398
///
1399
/// This type implements the `AsyncRead` trait to read data from the stdout
1400
/// handle of a child process asynchronously.
1401
#[derive(Debug)]
1402
pub struct ChildStdout {
1403
    inner: imp::ChildStdio,
1404
}
1405
1406
/// The standard error stream for spawned children.
1407
///
1408
/// This type implements the `AsyncRead` trait to read data from the stderr
1409
/// handle of a child process asynchronously.
1410
#[derive(Debug)]
1411
pub struct ChildStderr {
1412
    inner: imp::ChildStdio,
1413
}
1414
1415
impl ChildStdin {
1416
    /// Creates an asynchronous `ChildStdin` from a synchronous one.
1417
    ///
1418
    /// # Errors
1419
    ///
1420
    /// This method may fail if an error is encountered when setting the pipe to
1421
    /// non-blocking mode, or when registering the pipe with the runtime's IO
1422
    /// driver.
1423
0
    pub fn from_std(inner: std::process::ChildStdin) -> io::Result<Self> {
1424
        Ok(Self {
1425
0
            inner: imp::stdio(inner)?,
1426
        })
1427
0
    }
1428
}
1429
1430
impl ChildStdout {
1431
    /// Creates an asynchronous `ChildStdout` from a synchronous one.
1432
    ///
1433
    /// # Errors
1434
    ///
1435
    /// This method may fail if an error is encountered when setting the pipe to
1436
    /// non-blocking mode, or when registering the pipe with the runtime's IO
1437
    /// driver.
1438
0
    pub fn from_std(inner: std::process::ChildStdout) -> io::Result<Self> {
1439
        Ok(Self {
1440
0
            inner: imp::stdio(inner)?,
1441
        })
1442
0
    }
1443
}
1444
1445
impl ChildStderr {
1446
    /// Creates an asynchronous `ChildStderr` from a synchronous one.
1447
    ///
1448
    /// # Errors
1449
    ///
1450
    /// This method may fail if an error is encountered when setting the pipe to
1451
    /// non-blocking mode, or when registering the pipe with the runtime's IO
1452
    /// driver.
1453
0
    pub fn from_std(inner: std::process::ChildStderr) -> io::Result<Self> {
1454
        Ok(Self {
1455
0
            inner: imp::stdio(inner)?,
1456
        })
1457
0
    }
1458
}
1459
1460
impl AsyncWrite for ChildStdin {
1461
0
    fn poll_write(
1462
0
        mut self: Pin<&mut Self>,
1463
0
        cx: &mut Context<'_>,
1464
0
        buf: &[u8],
1465
0
    ) -> Poll<io::Result<usize>> {
1466
0
        Pin::new(&mut self.inner).poll_write(cx, buf)
1467
0
    }
1468
1469
0
    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1470
0
        Pin::new(&mut self.inner).poll_flush(cx)
1471
0
    }
1472
1473
0
    fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
1474
0
        Pin::new(&mut self.inner).poll_shutdown(cx)
1475
0
    }
1476
1477
0
    fn poll_write_vectored(
1478
0
        mut self: Pin<&mut Self>,
1479
0
        cx: &mut Context<'_>,
1480
0
        bufs: &[io::IoSlice<'_>],
1481
0
    ) -> Poll<Result<usize, io::Error>> {
1482
0
        Pin::new(&mut self.inner).poll_write_vectored(cx, bufs)
1483
0
    }
1484
1485
0
    fn is_write_vectored(&self) -> bool {
1486
0
        self.inner.is_write_vectored()
1487
0
    }
1488
}
1489
1490
impl AsyncRead for ChildStdout {
1491
0
    fn poll_read(
1492
0
        mut self: Pin<&mut Self>,
1493
0
        cx: &mut Context<'_>,
1494
0
        buf: &mut ReadBuf<'_>,
1495
0
    ) -> Poll<io::Result<()>> {
1496
0
        Pin::new(&mut self.inner).poll_read(cx, buf)
1497
0
    }
1498
}
1499
1500
impl AsyncRead for ChildStderr {
1501
0
    fn poll_read(
1502
0
        mut self: Pin<&mut Self>,
1503
0
        cx: &mut Context<'_>,
1504
0
        buf: &mut ReadBuf<'_>,
1505
0
    ) -> Poll<io::Result<()>> {
1506
0
        Pin::new(&mut self.inner).poll_read(cx, buf)
1507
0
    }
1508
}
1509
1510
impl TryInto<Stdio> for ChildStdin {
1511
    type Error = io::Error;
1512
1513
0
    fn try_into(self) -> Result<Stdio, Self::Error> {
1514
0
        imp::convert_to_stdio(self.inner)
1515
0
    }
1516
}
1517
1518
impl TryInto<Stdio> for ChildStdout {
1519
    type Error = io::Error;
1520
1521
0
    fn try_into(self) -> Result<Stdio, Self::Error> {
1522
0
        imp::convert_to_stdio(self.inner)
1523
0
    }
1524
}
1525
1526
impl TryInto<Stdio> for ChildStderr {
1527
    type Error = io::Error;
1528
1529
0
    fn try_into(self) -> Result<Stdio, Self::Error> {
1530
0
        imp::convert_to_stdio(self.inner)
1531
0
    }
1532
}
1533
1534
#[cfg(unix)]
1535
#[cfg_attr(docsrs, doc(cfg(unix)))]
1536
mod sys {
1537
    use std::{
1538
        io,
1539
        os::unix::io::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd},
1540
    };
1541
1542
    use super::{ChildStderr, ChildStdin, ChildStdout};
1543
1544
    macro_rules! impl_traits {
1545
        ($type:ty) => {
1546
            impl $type {
1547
                /// Convert into [`OwnedFd`].
1548
0
                pub fn into_owned_fd(self) -> io::Result<OwnedFd> {
1549
0
                    self.inner.into_owned_fd()
1550
0
                }
Unexecuted instantiation: <tokio::process::ChildStdin>::into_owned_fd
Unexecuted instantiation: <tokio::process::ChildStdout>::into_owned_fd
Unexecuted instantiation: <tokio::process::ChildStderr>::into_owned_fd
1551
            }
1552
1553
            impl AsRawFd for $type {
1554
0
                fn as_raw_fd(&self) -> RawFd {
1555
0
                    self.inner.as_raw_fd()
1556
0
                }
Unexecuted instantiation: <tokio::process::ChildStdout as std::os::fd::raw::AsRawFd>::as_raw_fd
Unexecuted instantiation: <tokio::process::ChildStderr as std::os::fd::raw::AsRawFd>::as_raw_fd
Unexecuted instantiation: <tokio::process::ChildStdin as std::os::fd::raw::AsRawFd>::as_raw_fd
1557
            }
1558
1559
            impl AsFd for $type {
1560
0
                fn as_fd(&self) -> BorrowedFd<'_> {
1561
0
                    unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
1562
0
                }
Unexecuted instantiation: <tokio::process::ChildStdin as std::os::fd::owned::AsFd>::as_fd
Unexecuted instantiation: <tokio::process::ChildStdout as std::os::fd::owned::AsFd>::as_fd
Unexecuted instantiation: <tokio::process::ChildStderr as std::os::fd::owned::AsFd>::as_fd
1563
            }
1564
        };
1565
    }
1566
1567
    impl_traits!(ChildStdin);
1568
    impl_traits!(ChildStdout);
1569
    impl_traits!(ChildStderr);
1570
}
1571
1572
#[cfg(any(windows, docsrs))]
1573
#[cfg_attr(docsrs, doc(cfg(windows)))]
1574
mod windows {
1575
    use super::*;
1576
    use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, OwnedHandle, RawHandle};
1577
1578
    #[cfg(not(docsrs))]
1579
    macro_rules! impl_traits {
1580
        ($type:ty) => {
1581
            impl $type {
1582
                /// Convert into [`OwnedHandle`].
1583
                pub fn into_owned_handle(self) -> io::Result<OwnedHandle> {
1584
                    self.inner.into_owned_handle()
1585
                }
1586
            }
1587
1588
            impl AsRawHandle for $type {
1589
                fn as_raw_handle(&self) -> RawHandle {
1590
                    self.inner.as_raw_handle()
1591
                }
1592
            }
1593
1594
            impl AsHandle for $type {
1595
                fn as_handle(&self) -> BorrowedHandle<'_> {
1596
                    unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
1597
                }
1598
            }
1599
        };
1600
    }
1601
1602
    #[cfg(docsrs)]
1603
    macro_rules! impl_traits {
1604
        ($type:ty) => {
1605
            impl $type {
1606
                /// Convert into [`OwnedHandle`].
1607
                pub fn into_owned_handle(self) -> io::Result<OwnedHandle> {
1608
                    todo!("For doc generation only")
1609
                }
1610
            }
1611
1612
            impl AsRawHandle for $type {
1613
                fn as_raw_handle(&self) -> RawHandle {
1614
                    todo!("For doc generation only")
1615
                }
1616
            }
1617
1618
            impl AsHandle for $type {
1619
                fn as_handle(&self) -> BorrowedHandle<'_> {
1620
                    todo!("For doc generation only")
1621
                }
1622
            }
1623
        };
1624
    }
1625
1626
    impl_traits!(ChildStdin);
1627
    impl_traits!(ChildStdout);
1628
    impl_traits!(ChildStderr);
1629
}
1630
1631
#[cfg(all(test, not(loom)))]
1632
mod test {
1633
    use super::kill::Kill;
1634
    use super::ChildDropGuard;
1635
1636
    use futures::future::FutureExt;
1637
    use std::future::Future;
1638
    use std::io;
1639
    use std::pin::Pin;
1640
    use std::task::{Context, Poll};
1641
1642
    struct Mock {
1643
        num_kills: usize,
1644
        num_polls: usize,
1645
        poll_result: Poll<Result<(), ()>>,
1646
    }
1647
1648
    impl Mock {
1649
        fn new() -> Self {
1650
            Self::with_result(Poll::Pending)
1651
        }
1652
1653
        fn with_result(result: Poll<Result<(), ()>>) -> Self {
1654
            Self {
1655
                num_kills: 0,
1656
                num_polls: 0,
1657
                poll_result: result,
1658
            }
1659
        }
1660
    }
1661
1662
    impl Kill for Mock {
1663
        fn kill(&mut self) -> io::Result<()> {
1664
            self.num_kills += 1;
1665
            Ok(())
1666
        }
1667
    }
1668
1669
    impl Future for Mock {
1670
        type Output = Result<(), ()>;
1671
1672
        fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
1673
            let inner = Pin::get_mut(self);
1674
            inner.num_polls += 1;
1675
            inner.poll_result
1676
        }
1677
    }
1678
1679
    #[test]
1680
    fn kills_on_drop_if_specified() {
1681
        let mut mock = Mock::new();
1682
1683
        {
1684
            let guard = ChildDropGuard {
1685
                inner: &mut mock,
1686
                kill_on_drop: true,
1687
            };
1688
            drop(guard);
1689
        }
1690
1691
        assert_eq!(1, mock.num_kills);
1692
        assert_eq!(0, mock.num_polls);
1693
    }
1694
1695
    #[test]
1696
    fn no_kill_on_drop_by_default() {
1697
        let mut mock = Mock::new();
1698
1699
        {
1700
            let guard = ChildDropGuard {
1701
                inner: &mut mock,
1702
                kill_on_drop: false,
1703
            };
1704
            drop(guard);
1705
        }
1706
1707
        assert_eq!(0, mock.num_kills);
1708
        assert_eq!(0, mock.num_polls);
1709
    }
1710
1711
    #[test]
1712
    fn no_kill_if_already_killed() {
1713
        let mut mock = Mock::new();
1714
1715
        {
1716
            let mut guard = ChildDropGuard {
1717
                inner: &mut mock,
1718
                kill_on_drop: true,
1719
            };
1720
            let _ = guard.kill();
1721
            drop(guard);
1722
        }
1723
1724
        assert_eq!(1, mock.num_kills);
1725
        assert_eq!(0, mock.num_polls);
1726
    }
1727
1728
    #[test]
1729
    fn no_kill_if_reaped() {
1730
        let mut mock_pending = Mock::with_result(Poll::Pending);
1731
        let mut mock_reaped = Mock::with_result(Poll::Ready(Ok(())));
1732
        let mut mock_err = Mock::with_result(Poll::Ready(Err(())));
1733
1734
        let waker = futures::task::noop_waker();
1735
        let mut context = Context::from_waker(&waker);
1736
        {
1737
            let mut guard = ChildDropGuard {
1738
                inner: &mut mock_pending,
1739
                kill_on_drop: true,
1740
            };
1741
            let _ = guard.poll_unpin(&mut context);
1742
1743
            let mut guard = ChildDropGuard {
1744
                inner: &mut mock_reaped,
1745
                kill_on_drop: true,
1746
            };
1747
            let _ = guard.poll_unpin(&mut context);
1748
1749
            let mut guard = ChildDropGuard {
1750
                inner: &mut mock_err,
1751
                kill_on_drop: true,
1752
            };
1753
            let _ = guard.poll_unpin(&mut context);
1754
        }
1755
1756
        assert_eq!(1, mock_pending.num_kills);
1757
        assert_eq!(1, mock_pending.num_polls);
1758
1759
        assert_eq!(0, mock_reaped.num_kills);
1760
        assert_eq!(1, mock_reaped.num_polls);
1761
1762
        assert_eq!(1, mock_err.num_kills);
1763
        assert_eq!(1, mock_err.num_polls);
1764
    }
1765
}