Skip to content

Fix broken pipe error, issue #192 - #195

Open
GunterSchmidt wants to merge 4 commits into
uutils:mainfrom
GunterSchmidt:SIGPIPE-panic-on-broken-pipe
Open

GunterSchmidt wants to merge 4 commits into
uutils:mainfrom
GunterSchmidt:SIGPIPE-panic-on-broken-pipe

Conversation

@GunterSchmidt

@GunterSchmidt GunterSchmidt commented Mar 9, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #192 with code used in coreutils.

@GunterSchmidt

Copy link
Copy Markdown
Contributor Author

This fix will return

>diffutils diff /etc/pacman.conf /dev/null | :
diffutils: write error: Broken pipe

while GNU diff does suppresses it completely.

This could easily be changed, but I prefer to output this error message.

Reason: Using diff on different files should return exit code 1, but returns in this case 0 without an error message. This is completely wrong information to the user.

This version sets exit code 1, which seems correct, since |: would not produce an error if no output was written as in the equal case.

@sylvestre

Copy link
Copy Markdown
Collaborator

could you please fix the conflicts? thanks

Comment thread Cargo.toml
regex = "1.10.4"
same-file = "1.0.6"
unicode-width = "0.2.0"
uucore = "0.6.0"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pulling the whole uucore (fluent, unic-langid, …) just for one error message seems too much
please do it with std, format_io_error is already there

Comment thread src/cmp.rs
);
}
println!();
// Instead of println!(), which panics in case of error (> /dev/full).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the print! just above will panic the same way on /dev/full

Comment thread src/cmp.rs
let mut stdout = io::stdout();
if let Err(e) = writeln!(stdout) {
return Err(format_io_error(&e));
};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could use ? with map_err instead of the if let + stray ;

Comment thread src/diff.rs
@@ -91,7 +92,26 @@ pub fn main(opts: Peekable<ArgsOs>) -> ExitCode {
params.to.to_string_lossy()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this println! still panics with --brief | :, no?

Comment thread src/diff.rs
);
} else {
io::stdout().write_all(&result).unwrap();
let result = io::stdout().write_all(&result);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add tests in tests/integration.rs for both /dev/full and a closed pipe, for diff and cmp

Comment thread src/diff.rs
uucore::show_error!("{err}");
#[cfg(unix)]
if uucore::signals::sigpipe_was_ignored() {
uucore::error::set_exit_code(1);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this doing anything? diff returns its own ExitCode, uucore's exit code is never read

Comment thread src/utils.rs
)
}

pub fn format_io_error(error: &dyn std::error::Error) -> String {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing the regex is fine but unrelated, could you please split it out?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SIGPIPE panics

2 participants