mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
tail: fix bug when following /dev/stdin
main panics when following /dev/stdin since /dev/stdin is not seekable. Check to see if file is seekable and use unbounded_seek if so. Also `tail -f` with no files should not follow stdin.
This commit is contained in:
parent
69e64e6c51
commit
3a0c23561e
2 changed files with 20 additions and 19 deletions
|
@ -146,8 +146,8 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
|||
let files = given_options.free;
|
||||
|
||||
if files.is_empty() {
|
||||
let buffer = BufReader::new(stdin());
|
||||
unbounded_tail(buffer, &settings);
|
||||
let mut buffer = BufReader::new(stdin());
|
||||
unbounded_tail(&mut buffer, &settings);
|
||||
} else {
|
||||
let mut multiple = false;
|
||||
let mut first_header = true;
|
||||
|
@ -168,13 +168,20 @@ pub fn uumain(args: Vec<String>) -> i32 {
|
|||
if path.is_dir() {
|
||||
continue;
|
||||
}
|
||||
let file = File::open(&path).unwrap();
|
||||
let mut file = File::open(&path).unwrap();
|
||||
if is_seekable(&mut file) {
|
||||
bounded_tail(&file, &settings);
|
||||
|
||||
if settings.follow {
|
||||
let reader = BufReader::new(file);
|
||||
readers.push(reader);
|
||||
}
|
||||
} else {
|
||||
let mut reader = BufReader::new(file);
|
||||
unbounded_tail(&mut reader, &settings);
|
||||
if settings.follow {
|
||||
readers.push(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if settings.follow {
|
||||
|
@ -419,7 +426,7 @@ fn bounded_tail(mut file: &File, settings: &Settings) {
|
|||
}
|
||||
}
|
||||
|
||||
fn unbounded_tail<T: Read>(mut reader: BufReader<T>, settings: &Settings) {
|
||||
fn unbounded_tail<T: Read>(reader: &mut BufReader<T>, settings: &Settings) {
|
||||
// Read through each line/char and store them in a ringbuffer that always
|
||||
// contains count lines/chars. When reaching the end of file, output the
|
||||
// data in the ringbuf.
|
||||
|
@ -487,10 +494,10 @@ fn unbounded_tail<T: Read>(mut reader: BufReader<T>, settings: &Settings) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if settings.follow {
|
||||
follow(&mut [reader], &["stdin".to_string()], settings);
|
||||
}
|
||||
fn is_seekable<T: Seek>(file: &mut T) -> bool {
|
||||
file.seek(SeekFrom::Current(0)).is_ok()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -80,13 +80,7 @@ fn test_follow_multiple() {
|
|||
|
||||
#[test]
|
||||
fn test_follow_stdin() {
|
||||
let (at, mut ucmd) = at_and_ucmd();
|
||||
let mut child = ucmd.arg("-f").pipe_in(at.read(FOOBAR_TXT)).run_no_wait();
|
||||
|
||||
let expected = at.read("follow_stdin.expected");
|
||||
assert_eq!(read_size(&mut child, expected.len()), expected);
|
||||
|
||||
child.kill().unwrap();
|
||||
new_ucmd().arg("-f").pipe_in_fixture(FOOBAR_TXT).run().stdout_is_fixture("follow_stdin.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue