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
12use std::process::Stdio;
13use std::time::Duration;
14use tokio::io::AsyncWriteExt;
15use tokio::process::Command;
16use tokio::time;
17use tokio_test::assert_err;
18
19#[tokio::test]
20async 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::sleep(Duration::from_secs(1)).await;
40
41 // Kill the child process.
42 child.kill().await.unwrap();
43
44 assert_err!(handle.await);
45}
46