+
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions tests/by-util/test_cat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,32 @@ use uutests::util::TestScenario;
use uutests::util::vec_of_size;
use uutests::util_name;

#[cfg(unix)]
// Verify cat handles a broken pipe on stdout without hanging or crashing and exits nonzero
#[test]
fn test_cat_broken_pipe_nonzero_and_message() {
use std::fs::File;
use std::os::unix::io::FromRawFd;
use uutests::new_ucmd;

unsafe {
let mut fds: [libc::c_int; 2] = [0, 0];
assert_eq!(libc::pipe(fds.as_mut_ptr()), 0, "Failed to create pipe");
// Close the read end to simulate a broken pipe on stdout
let read_end = File::from_raw_fd(fds[0]);
// Explicitly drop the read-end so writers see EPIPE instead of blocking on a full pipe
std::mem::drop(read_end);
let write_end = File::from_raw_fd(fds[1]);

let content = (0..10000).map(|_| "x").collect::<String>();
// On Unix, SIGPIPE should lead to a non-zero exit; ensure process exits and fails
new_ucmd!()
.set_stdout(write_end)
.pipe_in(content.as_bytes())
.fails();
}
}

#[test]
fn test_output_simple() {
new_ucmd!()
Expand Down
29 changes: 29 additions & 0 deletions tests/by-util/test_stdbuf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ fn invalid_input() {
new_ucmd!().arg("-/").fails_with_code(125);
}

#[cfg(not(feature = "feat_external_libstdbuf"))]
#[test]
fn test_permission() {
new_ucmd!()
Expand All @@ -24,6 +25,23 @@ fn test_permission() {
.stderr_contains("Permission denied");
}

// TODO: Tests below are brittle when feat_external_libstdbuf is enabled and libstdbuf is not installed.
// Align stdbuf with GNU search order to enable deterministic testing without installation:
// 1) search for libstdbuf next to the stdbuf binary, 2) then in LIBSTDBUF_DIR, 3) then system locations.
// After implementing this, rework tests to provide a temporary symlink rather than depending on system state.

#[cfg(feature = "feat_external_libstdbuf")]
#[test]
fn test_permission_external_missing_lib() {
// When built with external libstdbuf, running stdbuf fails early if lib is not installed
new_ucmd!()
.arg("-o1")
.arg(".")
.fails_with_code(1)
.stderr_contains("External libstdbuf not found");
}

#[cfg(not(feature = "feat_external_libstdbuf"))]
#[test]
fn test_no_such() {
new_ucmd!()
Expand All @@ -33,6 +51,17 @@ fn test_no_such() {
.stderr_contains("No such file or directory");
}

#[cfg(feature = "feat_external_libstdbuf")]
#[test]
fn test_no_such_external_missing_lib() {
// With external lib mode and missing installation, stdbuf fails before spawning the command
new_ucmd!()
.arg("-o1")
.arg("no_such")
.fails_with_code(1)
.stderr_contains("External libstdbuf not found");
}

// Disabled on x86_64-unknown-linux-musl because the cross-rs Docker image for this target
// does not provide musl-compiled system utilities (like head), leading to dynamic linker errors
// when preloading musl-compiled libstdbuf.so into glibc-compiled binaries. Same thing for FreeBSD.
Expand Down
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载