diff --git a/src/uu/tail/src/tail.rs b/src/uu/tail/src/tail.rs index 0b7ec01e7a8..d15aef55a07 100644 --- a/src/uu/tail/src/tail.rs +++ b/src/uu/tail/src/tail.rs @@ -175,7 +175,7 @@ fn tail_file( && file.is_seekable(if input.is_stdin() { offset } else { 0 }) && (!st.is_file() || st.len() > blksize_limit) { - bounded_tail(&mut file, settings); + bounded_tail(&mut file, settings)?; reader = BufReader::new(file); } else { reader = BufReader::new(file); @@ -466,7 +466,7 @@ fn backwards_thru_file(file: &mut File, num_delimiters: u64, delimiter: u8) { /// end of the file, and then read the file "backwards" in blocks of size /// `BLOCK_SIZE` until we find the location of the first line/byte. This ends up /// being a nice performance win for very large files. -fn bounded_tail(file: &mut File, settings: &Settings) { +fn bounded_tail(file: &mut File, settings: &Settings) -> UResult<()> { debug_assert!(!settings.presume_input_pipe); let mut limit = None; @@ -499,7 +499,8 @@ fn bounded_tail(file: &mut File, settings: &Settings) { _ => {} } - print_target_section(file, limit); + print_target_section(file, limit)?; + Ok(()) } fn unbounded_tail(reader: &mut BufReader, settings: &Settings) -> UResult<()> { @@ -580,7 +581,7 @@ fn unbounded_tail(reader: &mut BufReader, settings: &Settings) -> UR Ok(()) } -fn print_target_section(file: &mut R, limit: Option) +fn print_target_section(file: &mut R, limit: Option) -> UResult<()> where R: Read + ?Sized, { @@ -589,10 +590,11 @@ where let mut stdout = stdout.lock(); if let Some(limit) = limit { let mut reader = file.take(limit); - io::copy(&mut reader, &mut stdout).unwrap(); + io::copy(&mut reader, &mut stdout)?; } else { - io::copy(file, &mut stdout).unwrap(); + io::copy(file, &mut stdout)?; } + Ok(()) } #[cfg(test)] diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index c1b755bda78..d46ff112c4a 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -5086,6 +5086,21 @@ fn test_failed_write_is_reported() { .stderr_is("tail: No space left on device\n"); } +#[cfg(target_os = "linux")] +#[test] +fn test_failed_write_is_reported_on_seekable_input() { + let ts = TestScenario::new("tail"); + let at = &ts.fixtures; + + at.write("bigfile", &"x\n".repeat(1_100_000)); + + ts.ucmd() + .arg("bigfile") + .set_stdout(File::create("/dev/full").unwrap()) + .fails() + .stderr_is("tail: No space left on device\n"); +} + #[test] #[cfg(target_os = "linux")] fn test_dev_zero() {