1 #![cfg(feature = "process")]
2 #![warn(rust_2018_idioms)]
3 // This test reveals a difference in behavior of kqueue on FreeBSD. When the
4 // reader disconnects, there does not seem to be an `EVFILT_WRITE` filter that
5 // is returned.
6 //
7 // It is expected that `EVFILT_WRITE` would be returned with either the
8 // `EV_EOF` or `EV_ERROR` flag set. If either flag is set a write would be
9 // attempted, but that does not seem to occur.
10 #![cfg(all(unix, not(target_os = "freebsd")))]
11 
12 use std::process::Stdio;
13 use std::time::Duration;
14 use tokio::prelude::*;
15 use tokio::process::Command;
16 use tokio::time;
17 use tokio_test::assert_err;
18 
19 #[tokio::test]
issue_2174()20 async fn issue_2174() {
21     let mut child = Command::new("sleep")
22         .arg("2")
23         .stdin(Stdio::piped())
24         .stdout(Stdio::null())
25         .spawn()
26         .unwrap();
27     let mut input = child.stdin.take().unwrap();
28 
29     // Writes will buffer up to 65_636. This *should* loop at least 8 times
30     // and then register interest.
31     let handle = tokio::spawn(async move {
32         let data = [0u8; 8192];
33         loop {
34             input.write_all(&data).await.unwrap();
35         }
36     });
37 
38     // Sleep enough time so that the child process's stdin's buffer fills.
39     time::delay_for(Duration::from_secs(1)).await;
40 
41     // Kill the child process.
42     child.kill().unwrap();
43     let _ = child.await;
44 
45     assert_err!(handle.await);
46 }
47