From cd0d23752a2d3f0ce8e4094dbfa66ce1705ff6c1 Mon Sep 17 00:00:00 2001 From: Jan Scheer Date: Wed, 8 Sep 2021 02:09:09 +0200 Subject: [PATCH] tail: add fixes to pass "gnu/tests/tail-2/tail-c.sh" from GNU's test suite --- src/uu/tail/src/tail.rs | 20 ++++++++++++++++++-- tests/by-util/test_tail.rs | 20 ++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/uu/tail/src/tail.rs b/src/uu/tail/src/tail.rs index 44f910ea0..89fbe4d36 100644 --- a/src/uu/tail/src/tail.rs +++ b/src/uu/tail/src/tail.rs @@ -22,7 +22,7 @@ use chunks::ReverseChunks; use clap::{App, Arg}; use std::collections::VecDeque; use std::fmt; -use std::fs::File; +use std::fs::{File, Metadata}; use std::io::{stdin, stdout, BufRead, BufReader, Read, Seek, SeekFrom, Write}; use std::path::Path; use std::thread::sleep; @@ -32,6 +32,8 @@ use uucore::ringbuffer::RingBuffer; #[cfg(unix)] use crate::platform::stdin_is_pipe_or_fifo; +#[cfg(unix)] +use std::os::unix::fs::MetadataExt; pub mod options { pub mod verbosity { @@ -189,7 +191,8 @@ pub fn uumain(args: impl uucore::Args) -> i32 { continue; } let mut file = File::open(&path).unwrap(); - if is_seekable(&mut file) { + let md = file.metadata().unwrap(); + if is_seekable(&mut file) && get_block_size(&md) > 0 { bounded_tail(&mut file, &settings); if settings.follow { let reader = BufReader::new(file); @@ -437,6 +440,8 @@ fn unbounded_tail(reader: &mut BufReader, settings: &Settings) { fn is_seekable(file: &mut T) -> bool { file.seek(SeekFrom::Current(0)).is_ok() + && file.seek(SeekFrom::End(0)).is_ok() + && file.seek(SeekFrom::Start(0)).is_ok() } #[inline] @@ -464,3 +469,14 @@ fn parse_num(src: &str) -> Result<(usize, bool), ParseSizeError> { parse_size(size_string).map(|n| (n, starting_with)) } + +fn get_block_size(md: &Metadata) -> u64 { + #[cfg(unix)] + { + md.blocks() + } + #[cfg(not(unix))] + { + md.len() + } +} diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index 28c3580bb..26d8106f0 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -425,3 +425,23 @@ fn test_tail_num_with_undocumented_sign_bytes() { .succeeds() .stdout_is("efghijklmnopqrstuvwxyz"); } + +#[test] +#[cfg(unix)] +fn test_tail_bytes_for_funny_files() { + // gnu/tests/tail-2/tail-c.sh + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + for &file in &["/proc/version", "/sys/kernel/profiling"] { + if !at.file_exists(file) { + continue; + } + let args = ["--bytes", "1", file]; + let result = ts.ucmd().args(&args).run(); + let exp_result = unwrap_or_return!(expected_result(&ts, &args)); + result + .stdout_is(exp_result.stdout_str()) + .stderr_is(exp_result.stderr_str()) + .code_is(exp_result.code()); + } +}