1use async_io::Timer;
4use async_process::{Command, Stdio};
5use futures_lite::{future, prelude::*};
6use std::io;
7
8fn main() -> io::Result<()> {
9 async_io::block_on(async {
10 let mut child = Command::new("sleep")
12 .arg("3")
13 .stdout(Stdio::piped())
14 .stderr(Stdio::piped())
15 .spawn()?;
16
17 let mut stdout = String::new();
21 let drain_stdout = {
22 let buffer = &mut stdout;
23 let mut stdout = child.stdout.take().unwrap();
24
25 async move {
26 stdout.read_to_string(buffer).await?;
27
28 future::pending().await
30 }
31 };
32
33 let mut stderr = String::new();
35 let drain_stderr = {
36 let buffer = &mut stderr;
37 let mut stderr = child.stderr.take().unwrap();
38
39 async move {
40 stderr.read_to_string(buffer).await?;
41
42 future::pending().await
44 }
45 };
46
47 let wait = async move {
49 child.status().await?;
50
51 io::Result::Ok(false)
53 };
54
55 let timeout_s = 1;
57 let timeout = async move {
58 Timer::after(std::time::Duration::from_secs(timeout_s)).await;
59
60 Ok(true)
62 };
63
64 let timed_out = drain_stdout.or(drain_stderr).or(wait).or(timeout).await?;
68
69 if timed_out {
70 println!("The child timed out.");
71 } else {
72 println!("The child exited.");
73 }
74
75 println!("Stdout:\n{stdout}");
76 println!("Stderr:\n{stderr}");
77
78 Ok(())
79 })
80}