blob: 66aa029e7a88fcfcf1b17d7d67cd2cf04ed43f48 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#![cfg(unix)]
use std::os::fd::{FromRawFd, OwnedFd};
use std::os::unix::process::ExitStatusExt;
use std::process::{Command, Output, Stdio};
fn closed_pipe_writer() -> Stdio {
let mut fds = [-1; 2];
assert_eq!(unsafe { libc::pipe(fds.as_mut_ptr()) }, 0);
// SAFETY: pipe initialized both descriptors, and each is assigned to one
// OwnedFd so it is closed exactly once.
let read_fd = unsafe { OwnedFd::from_raw_fd(fds[0]) };
let write_fd = unsafe { OwnedFd::from_raw_fd(fds[1]) };
drop(read_fd);
Stdio::from(write_fd)
}
fn run_with_closed_stdout(args: &[&str]) -> Output {
Command::new(env!("CARGO_BIN_EXE_herdr"))
.args(args)
.stdout(closed_pipe_writer())
.stderr(Stdio::piped())
.output()
.expect("run herdr CLI")
}
fn assert_quiet_sigpipe(output: Output) {
assert_eq!(output.status.signal(), Some(libc::SIGPIPE));
assert!(
output.stderr.is_empty(),
"closed stdout should not emit an error or panic: {}",
String::from_utf8_lossy(&output.stderr)
);
}
#[test]
fn cli_exits_via_sigpipe_without_panicking_when_stdout_closes() {
assert_quiet_sigpipe(run_with_closed_stdout(&["api", "schema", "--json"]));
}
#[test]
fn terminal_help_uses_cli_sigpipe_behavior_before_attach_starts() {
assert_quiet_sigpipe(run_with_closed_stdout(&["terminal", "attach", "--help"]));
}
#[test]
fn completion_direct_writer_uses_cli_sigpipe_behavior() {
assert_quiet_sigpipe(run_with_closed_stdout(&["completion", "bash"]));
}
|