From 820e804f8afc235dd36254c5f70a4663036cb811 Mon Sep 17 00:00:00 2001 From: mattsu Date: Mon, 24 Nov 2025 14:19:13 +0900 Subject: [PATCH 1/3] fix(seq): handle BrokenPipe like GNU --- src/uu/seq/src/seq.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/uu/seq/src/seq.rs b/src/uu/seq/src/seq.rs index 6741356606d..7b56c26f574 100644 --- a/src/uu/seq/src/seq.rs +++ b/src/uu/seq/src/seq.rs @@ -4,7 +4,7 @@ // file that was distributed with this source code. // spell-checker:ignore (ToDO) bigdecimal extendedbigdecimal numberparse hexadecimalfloat biguint use std::ffi::{OsStr, OsString}; -use std::io::{BufWriter, ErrorKind, Write, stdout}; +use std::io::{BufWriter, Write, stdout}; use clap::{Arg, ArgAction, Command}; use num_bigint::BigUint; @@ -211,7 +211,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { match result { Ok(()) => Ok(()), - Err(err) if err.kind() == ErrorKind::BrokenPipe => Ok(()), + Err(err) if err.kind() == std::io::ErrorKind::BrokenPipe => { + // GNU seq prints the Broken pipe message but still exits with status 0 + let err = err.map_err_context(|| "write error".into()); + uucore::show_error!("{err}"); + Ok(()) + } Err(err) => Err(err.map_err_context(|| "write error".into())), } } From 1d99af28ecc73295421033ea5e77bef0ecc1e568 Mon Sep 17 00:00:00 2001 From: mattsu Date: Wed, 26 Nov 2025 16:20:39 +0900 Subject: [PATCH 2/3] test: add Unix-specific test for seq command broken pipe handling - Ensures seq exits gracefully with code 0 and reports "Broken pipe" error on stderr when stdout pipe is prematurely closed - Validates correct behavior for common scenario where output is piped to commands like head that terminate early --- tests/by-util/test_seq.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/by-util/test_seq.rs b/tests/by-util/test_seq.rs index f82a6228fe1..238f634c8d0 100644 --- a/tests/by-util/test_seq.rs +++ b/tests/by-util/test_seq.rs @@ -10,6 +10,25 @@ fn test_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails_with_code(1); } +#[test] +#[cfg(unix)] +fn test_broken_pipe_still_exits_success() { + use std::process::Stdio; + + let mut child = new_ucmd!() + .args(&["1", "5"]) + .set_stdout(Stdio::piped()) + .run_no_wait(); + + // 出力先が先に閉じられたパイプへ書こうとして Broken pipe を発生させる。 + child.close_stdout(); + let result = child.wait().unwrap(); + + result + .code_is(0) + .stderr_contains("write error: Broken pipe"); +} + #[test] fn test_no_args() { new_ucmd!() From f9a517bcd0f106db058e8029d396acf9b0156ac1 Mon Sep 17 00:00:00 2001 From: mattsu Date: Wed, 26 Nov 2025 20:06:24 +0900 Subject: [PATCH 3/3] refactor(test): translate Japanese comment to English in test_seq.rs - Updated a comment in the test for broken pipe behavior to use English instead of Japanese, enhancing readability for non-Japanese speakers and aligning with project standards. No functional changes to the test logic. --- tests/by-util/test_seq.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_seq.rs b/tests/by-util/test_seq.rs index 238f634c8d0..de0ad10d9fb 100644 --- a/tests/by-util/test_seq.rs +++ b/tests/by-util/test_seq.rs @@ -20,7 +20,7 @@ fn test_broken_pipe_still_exits_success() { .set_stdout(Stdio::piped()) .run_no_wait(); - // 出力先が先に閉じられたパイプへ書こうとして Broken pipe を発生させる。 + // Trigger a Broken pipe by writing to a pipe whose reader closed first. child.close_stdout(); let result = child.wait().unwrap();