diff --git a/src/uu/tail/src/follow/files.rs b/src/uu/tail/src/follow/files.rs index f043703becc..8b1f64bf2a7 100644 --- a/src/uu/tail/src/follow/files.rs +++ b/src/uu/tail/src/follow/files.rs @@ -143,7 +143,7 @@ impl FileHandling { if chunks.has_data() { if self.needs_header(path, verbose) { let display_name = self.get(path).display_name.clone(); - self.header_printer.print(display_name.as_str()); + self.header_printer.print(display_name.as_str())?; } let mut writer = BufWriter::new(stdout().lock()); diff --git a/src/uu/tail/src/paths.rs b/src/uu/tail/src/paths.rs index aa9a81b708d..148dcb2a00c 100644 --- a/src/uu/tail/src/paths.rs +++ b/src/uu/tail/src/paths.rs @@ -8,7 +8,7 @@ use crate::text; use std::ffi::OsStr; use std::fs::{File, Metadata}; -use std::io::{Seek, SeekFrom}; +use std::io::{self, Seek, SeekFrom, Write, stdout}; #[cfg(unix)] use std::os::unix::fs::{FileTypeExt, MetadataExt}; use std::path::{Path, PathBuf}; @@ -127,18 +127,26 @@ impl HeaderPrinter { } } - pub fn print_input(&mut self, input: &Input) { - self.print(input.display_name.as_str()); + pub fn print_input(&mut self, input: &Input) -> io::Result<()> { + self.print(input.display_name.as_str()) } - pub fn print(&mut self, string: &str) { + pub fn print(&mut self, string: &str) -> io::Result<()> { if self.verbose { - println!( - "{}==> {string} <==", + let header_string = format!( + "{}==> {string} <==\n", if self.first_header { "" } else { "\n" }, ); + + let stdout = stdout(); + let mut stdout = stdout.lock(); + + stdout.write_all(header_string.as_bytes())?; + stdout.flush()?; + self.first_header = false; } + Ok(()) } } pub trait FileExtTail { diff --git a/src/uu/tail/src/tail.rs b/src/uu/tail/src/tail.rs index 72f6e57c0e4..2cf986a9d4a 100644 --- a/src/uu/tail/src/tail.rs +++ b/src/uu/tail/src/tail.rs @@ -136,7 +136,7 @@ fn tail_file( if path.is_dir() { set_exit_code(1); - header_printer.print_input(input); + header_printer.print_input(input)?; let err_msg = translate!("tail-is-a-directory"); show_error!( @@ -168,7 +168,7 @@ fn tail_file( Ok(mut file) => { let st = file.metadata()?; let blksize_limit = uucore::fs::sane_blksize::sane_blksize_from_metadata(&st); - header_printer.print_input(input); + header_printer.print_input(input)?; let mut reader; if !settings.presume_input_pipe && file.is_seekable(if input.is_stdin() { offset } else { 0 }) @@ -304,7 +304,7 @@ fn tail_stdin( )?; } else { // pipe - header_printer.print_input(input); + header_printer.print_input(input)?; if paths::stdin_is_bad_fd() { set_exit_code(1); show_error!( diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index d4a4d123266..00255176193 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -5033,6 +5033,16 @@ fn test_failed_write_is_reported() { .stderr_is("tail: No space left on device\n"); } +#[cfg(target_os = "linux")] +#[test] +fn test_multiple_input_files_failed_write_is_reported() { + new_ucmd!() + .args(&["/etc/hosts", "/etc/hosts"]) + .set_stdout(File::create("/dev/full").unwrap()) + .fails() + .stderr_is("tail: No space left on device\n"); +} + #[cfg(target_os = "linux")] #[test] fn test_failed_write_is_reported_on_seekable_input() {