mirror of
https://github.com/uutils/coreutils.git
synced 2025-07-07 21:45:01 +00:00
Merge pull request #8298 from yuankunzhang/tr-broken-pipe
Some checks are pending
CICD / Test all features separately (push) Blocked by required conditions
CICD / Build/SELinux (push) Blocked by required conditions
CICD / Style/cargo-deny (push) Waiting to run
CICD / Style/deps (push) Waiting to run
CICD / Documentation/warnings (push) Waiting to run
CICD / MinRustV (push) Waiting to run
CICD / Dependencies (push) Waiting to run
CICD / Build/Makefile (push) Blocked by required conditions
CICD / Build/stable (push) Blocked by required conditions
CICD / Build/nightly (push) Blocked by required conditions
CICD / Binary sizes (push) Blocked by required conditions
CICD / Build (push) Blocked by required conditions
CICD / Tests/BusyBox test suite (push) Blocked by required conditions
CICD / Tests/Toybox test suite (push) Blocked by required conditions
CICD / Code Coverage (push) Waiting to run
CICD / Separate Builds (push) Waiting to run
GnuTests / Run GNU tests (push) Waiting to run
Android / Test builds (push) Waiting to run
Code Quality / Style/format (push) Waiting to run
Code Quality / Style/lint (push) Waiting to run
Code Quality / Style/spelling (push) Waiting to run
Code Quality / Style/toml (push) Waiting to run
Code Quality / Style/Python (push) Waiting to run
Code Quality / Pre-commit hooks (push) Waiting to run
FreeBSD / Style and Lint (push) Waiting to run
FreeBSD / Tests (push) Waiting to run
Some checks are pending
CICD / Test all features separately (push) Blocked by required conditions
CICD / Build/SELinux (push) Blocked by required conditions
CICD / Style/cargo-deny (push) Waiting to run
CICD / Style/deps (push) Waiting to run
CICD / Documentation/warnings (push) Waiting to run
CICD / MinRustV (push) Waiting to run
CICD / Dependencies (push) Waiting to run
CICD / Build/Makefile (push) Blocked by required conditions
CICD / Build/stable (push) Blocked by required conditions
CICD / Build/nightly (push) Blocked by required conditions
CICD / Binary sizes (push) Blocked by required conditions
CICD / Build (push) Blocked by required conditions
CICD / Tests/BusyBox test suite (push) Blocked by required conditions
CICD / Tests/Toybox test suite (push) Blocked by required conditions
CICD / Code Coverage (push) Waiting to run
CICD / Separate Builds (push) Waiting to run
GnuTests / Run GNU tests (push) Waiting to run
Android / Test builds (push) Waiting to run
Code Quality / Style/format (push) Waiting to run
Code Quality / Style/lint (push) Waiting to run
Code Quality / Style/spelling (push) Waiting to run
Code Quality / Style/toml (push) Waiting to run
Code Quality / Style/Python (push) Waiting to run
Code Quality / Pre-commit hooks (push) Waiting to run
FreeBSD / Style and Lint (push) Waiting to run
FreeBSD / Tests (push) Waiting to run
tr: handle broken pipe gracefully
This commit is contained in:
commit
854d9af125
3 changed files with 27 additions and 7 deletions
|
@ -708,9 +708,16 @@ where
|
|||
let filtered = buf.iter().filter_map(|&c| translator.translate(c));
|
||||
output_buf.extend(filtered);
|
||||
|
||||
output
|
||||
.write_all(&output_buf)
|
||||
.map_err_context(|| get_message("tr-error-write-error"))?;
|
||||
if let Err(err) = output.write_all(&output_buf) {
|
||||
// Treat broken pipe as a successful termination, which is the
|
||||
// expected behavior when stdout is a pipeline and the downstream
|
||||
// process terminates.
|
||||
if err.kind() == std::io::ErrorKind::BrokenPipe {
|
||||
break;
|
||||
} else {
|
||||
return Err(err.map_err_context(|| get_message("tr-error-write-error")));
|
||||
}
|
||||
}
|
||||
|
||||
buf.clear();
|
||||
output_buf.clear();
|
||||
|
|
|
@ -13,7 +13,7 @@ use operation::{
|
|||
};
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsString;
|
||||
use std::io::{BufWriter, Write, stdin, stdout};
|
||||
use std::io::{BufWriter, ErrorKind, Write, stdin, stdout};
|
||||
use uucore::display::Quotable;
|
||||
use uucore::error::{FromIo, UResult, USimpleError, UUsageError};
|
||||
use uucore::fs::is_stdin_directory;
|
||||
|
@ -157,9 +157,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
|||
translate_input(&mut locked_stdin, &mut buffered_stdout, op)?;
|
||||
}
|
||||
|
||||
buffered_stdout
|
||||
.flush()
|
||||
.map_err_context(|| get_message("tr-error-write-error"))?;
|
||||
// Handle broken pipe errors gracefully during flush.
|
||||
match buffered_stdout.flush() {
|
||||
Ok(()) => {}
|
||||
Err(err) if err.kind() == ErrorKind::BrokenPipe => {}
|
||||
Err(err) => return Err(err.map_err_context(|| get_message("tr-error-write-error"))),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1554,3 +1554,13 @@ fn test_failed_write_is_reported() {
|
|||
.fails()
|
||||
.stderr_is("tr: write error: No space left on device\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_broken_pipe_no_error() {
|
||||
new_ucmd!()
|
||||
.args(&["e", "a"])
|
||||
.pipe_in("hello".repeat(100))
|
||||
.run_stdout_starts_with(b"")
|
||||
.success()
|
||||
.stderr_is("");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue