1 #![cfg(all(unix, feature = "process"))]
2 #![warn(rust_2018_idioms)]
3 
4 use std::io::ErrorKind;
5 use std::process::Stdio;
6 use std::time::Duration;
7 use tokio::io::AsyncReadExt;
8 use tokio::process::Command;
9 use tokio::time::sleep;
10 use tokio_test::assert_ok;
11 
12 #[tokio::test]
kill_on_drop()13 async fn kill_on_drop() {
14     let mut cmd = Command::new("bash");
15     cmd.args(&[
16         "-c",
17         "
18        # Fork another child that won't get killed
19        sh -c 'sleep 1; echo child ran' &
20        disown -a
21 
22        # Await our death
23        sleep 5
24        echo hello from beyond the grave
25     ",
26     ]);
27 
28     let e = cmd.kill_on_drop(true).stdout(Stdio::piped()).spawn();
29     if e.is_err() && e.as_ref().unwrap_err().kind() == ErrorKind::NotFound {
30         println!("bash not available; skipping test");
31         return;
32     }
33     let mut child = e.unwrap();
34 
35     sleep(Duration::from_secs(2)).await;
36 
37     let mut out = child.stdout.take().unwrap();
38     drop(child);
39 
40     let mut msg = String::new();
41     assert_ok!(out.read_to_string(&mut msg).await);
42 
43     assert_eq!("child ran\n", msg);
44 }
45