mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
tail: update readmes
This commit is contained in:
parent
132cab15d2
commit
ceb2e993c0
4 changed files with 30 additions and 33 deletions
|
@ -422,10 +422,10 @@ See https://github.com/uutils/coreutils/issues/3336 for the main meta bugs
|
||||||
| comm | sort | |
|
| comm | sort | |
|
||||||
| csplit | split | |
|
| csplit | split | |
|
||||||
| cut | tac | |
|
| cut | tac | |
|
||||||
| dircolors | tail | |
|
| dircolors | test | |
|
||||||
| dirname | test | |
|
| dirname | dir | |
|
||||||
| du | dir | |
|
| du | vdir | |
|
||||||
| echo | vdir | |
|
| echo | | |
|
||||||
| env | | |
|
| env | | |
|
||||||
| expand | | |
|
| expand | | |
|
||||||
| factor | | |
|
| factor | | |
|
||||||
|
@ -478,6 +478,7 @@ See https://github.com/uutils/coreutils/issues/3336 for the main meta bugs
|
||||||
| stdbuf | | |
|
| stdbuf | | |
|
||||||
| sum | | |
|
| sum | | |
|
||||||
| sync | | |
|
| sync | | |
|
||||||
|
| tail | | |
|
||||||
| tee | | |
|
| tee | | |
|
||||||
| timeout | | |
|
| timeout | | |
|
||||||
| touch | | |
|
| touch | | |
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# Notes / ToDO
|
# Notes / ToDO
|
||||||
|
|
||||||
- Rudimentary tail implementation.
|
|
||||||
|
|
||||||
## Missing features
|
## Missing features
|
||||||
|
|
||||||
### Flags with features
|
### Flags with features
|
||||||
|
@ -11,13 +9,13 @@
|
||||||
- [ ] `--max-unchanged-stats` (only meaningful with `--follow=name` `---disable-inotify`)
|
- [ ] `--max-unchanged-stats` (only meaningful with `--follow=name` `---disable-inotify`)
|
||||||
- [x] `---disable-inotify` (three hyphens is correct)
|
- [x] `---disable-inotify` (three hyphens is correct)
|
||||||
- [x] `--follow=name'
|
- [x] `--follow=name'
|
||||||
- [ ] `--retry'
|
- [x] `--retry'
|
||||||
- [ ] `-F' (same as `--follow=name` `--retry`)
|
- [x] `-F' (same as `--follow=name` `--retry`)
|
||||||
|
|
||||||
### Others
|
### Others
|
||||||
|
|
||||||
- [ ] The current implementation doesn't follow stdin in non-unix platforms
|
- [ ] The current implementation doesn't follow stdin in non-unix platforms
|
||||||
- [ ] Since the current implementation uses a crate for polling, the following is difficult to implement:
|
- [ ] Since the current implementation uses a crate for polling, these flags are too complex to implement:
|
||||||
- [ ] `--max-unchanged-stats`
|
- [ ] `--max-unchanged-stats`
|
||||||
- [ ] check whether process p is alive at least every number of seconds (relevant for `--pid`)
|
- [ ] check whether process p is alive at least every number of seconds (relevant for `--pid`)
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,9 @@ use std::collections::HashMap;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fs::metadata;
|
|
||||||
use std::fs::{File, Metadata};
|
use std::fs::{File, Metadata};
|
||||||
use std::io::{stdin, stdout, BufRead, BufReader, Read, Seek, SeekFrom, Write};
|
use std::io::{stdin, stdout, BufRead, BufReader, Read, Seek, SeekFrom, Write};
|
||||||
use std::io::{Error, ErrorKind};
|
use std::io::{Error, ErrorKind};
|
||||||
use std::os::unix::prelude::FileTypeExt;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::mpsc::{self, channel};
|
use std::sync::mpsc::{self, channel};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -52,6 +50,10 @@ use uucore::ringbuffer::RingBuffer;
|
||||||
use crate::platform::stdin_is_pipe_or_fifo;
|
use crate::platform::stdin_is_pipe_or_fifo;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use std::os::unix::fs::MetadataExt;
|
use std::os::unix::fs::MetadataExt;
|
||||||
|
#[cfg(unix)]
|
||||||
|
use std::os::unix::prelude::FileTypeExt;
|
||||||
|
#[cfg(unix)]
|
||||||
|
use std::fs::metadata;
|
||||||
|
|
||||||
const ABOUT: &str = "\
|
const ABOUT: &str = "\
|
||||||
Print the last 10 lines of each FILE to standard output.\n\
|
Print the last 10 lines of each FILE to standard output.\n\
|
||||||
|
@ -85,7 +87,7 @@ pub mod options {
|
||||||
pub static PID: &str = "pid";
|
pub static PID: &str = "pid";
|
||||||
pub static SLEEP_INT: &str = "sleep-interval";
|
pub static SLEEP_INT: &str = "sleep-interval";
|
||||||
pub static ZERO_TERM: &str = "zero-terminated";
|
pub static ZERO_TERM: &str = "zero-terminated";
|
||||||
pub static DISABLE_INOTIFY_TERM: &str = "disable-inotify";
|
pub static DISABLE_INOTIFY_TERM: &str = "-disable-inotify";
|
||||||
pub static USE_POLLING: &str = "use-polling";
|
pub static USE_POLLING: &str = "use-polling";
|
||||||
pub static RETRY: &str = "retry";
|
pub static RETRY: &str = "retry";
|
||||||
pub static FOLLOW_RETRY: &str = "F";
|
pub static FOLLOW_RETRY: &str = "F";
|
||||||
|
@ -1302,8 +1304,16 @@ impl PathExt for Path {
|
||||||
!matches!(self.parent(), Some(parent) if parent.is_dir())
|
!matches!(self.parent(), Some(parent) if parent.is_dir())
|
||||||
}
|
}
|
||||||
fn is_tailable(&self) -> bool {
|
fn is_tailable(&self) -> bool {
|
||||||
// TODO: [2021-10; jhscheer] what about fifos?
|
#[cfg(unix)]
|
||||||
self.is_file() || (self.exists() && metadata(self).unwrap().file_type().is_char_device())
|
{
|
||||||
|
// TODO: [2021-10; jhscheer] what about fifos?
|
||||||
|
self.is_file()
|
||||||
|
|| (self.exists() && metadata(self).unwrap().file_type().is_char_device())
|
||||||
|
}
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
{
|
||||||
|
self.is_file()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -940,7 +940,7 @@ fn test_retry7() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(unix)]
|
#[cfg(all(unix, not(target_os = "android")))] // FIXME: fix this test for Android
|
||||||
fn test_retry8() {
|
fn test_retry8() {
|
||||||
// Ensure that inotify will switch to polling mode if directory
|
// Ensure that inotify will switch to polling mode if directory
|
||||||
// of the watched file was initially missing and later created.
|
// of the watched file was initially missing and later created.
|
||||||
|
@ -994,7 +994,7 @@ fn test_retry8() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(unix)]
|
#[cfg(all(unix, not(target_os = "android")))] // FIXME: fix this test for Android
|
||||||
fn test_retry9() {
|
fn test_retry9() {
|
||||||
// gnu/tests/tail-2/inotify-dir-recreate.sh
|
// gnu/tests/tail-2/inotify-dir-recreate.sh
|
||||||
// Ensure that inotify will switch to polling mode if directory
|
// Ensure that inotify will switch to polling mode if directory
|
||||||
|
@ -1069,7 +1069,7 @@ fn test_retry9() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(unix)]
|
#[cfg(target_os = "linux")] // FIXME: fix this test for BSD/macOS
|
||||||
fn test_follow_descriptor_vs_rename1() {
|
fn test_follow_descriptor_vs_rename1() {
|
||||||
// gnu/tests/tail-2/descriptor-vs-rename.sh
|
// gnu/tests/tail-2/descriptor-vs-rename.sh
|
||||||
// $ ((rm -f A && touch A && sleep 1 && echo -n "A\n" >> A && sleep 1 && \
|
// $ ((rm -f A && touch A && sleep 1 && echo -n "A\n" >> A && sleep 1 && \
|
||||||
|
@ -1092,14 +1092,8 @@ fn test_follow_descriptor_vs_rename1() {
|
||||||
"--disable-inotify",
|
"--disable-inotify",
|
||||||
];
|
];
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
let i = 2;
|
|
||||||
// FIXME: fix the case without `--disable-inotify` for BSD/macOS
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
|
||||||
let i = 1;
|
|
||||||
|
|
||||||
let delay = 500;
|
let delay = 500;
|
||||||
for _ in 0..i {
|
for _ in 0..2 {
|
||||||
at.touch(file_a);
|
at.touch(file_a);
|
||||||
|
|
||||||
let mut p = ts.ucmd().args(&args).run_no_wait();
|
let mut p = ts.ucmd().args(&args).run_no_wait();
|
||||||
|
@ -1152,14 +1146,8 @@ fn test_follow_descriptor_vs_rename2() {
|
||||||
"--disable-inotify",
|
"--disable-inotify",
|
||||||
];
|
];
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
let i = 2;
|
|
||||||
// TODO: fix the case without `--disable-inotify` for bsd/macos
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
|
||||||
let i = 1;
|
|
||||||
|
|
||||||
let delay = 100;
|
let delay = 100;
|
||||||
for _ in 0..i {
|
for _ in 0..2 {
|
||||||
at.touch(file_a);
|
at.touch(file_a);
|
||||||
at.touch(file_b);
|
at.touch(file_b);
|
||||||
let mut p = ts.ucmd().args(&args).run_no_wait();
|
let mut p = ts.ucmd().args(&args).run_no_wait();
|
||||||
|
@ -1324,7 +1312,7 @@ fn test_follow_name_truncate3() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(unix)]
|
#[cfg(all(unix, not(target_os = "android")))] // FIXME: fix this test for Android
|
||||||
fn test_follow_name_move_create() {
|
fn test_follow_name_move_create() {
|
||||||
// This test triggers a move/create event while `tail --follow=name logfile` is running.
|
// This test triggers a move/create event while `tail --follow=name logfile` is running.
|
||||||
// ((sleep 2 && mv logfile backup && sleep 2 && cp backup logfile &)>/dev/null 2>&1 &) ; tail --follow=name logfile
|
// ((sleep 2 && mv logfile backup && sleep 2 && cp backup logfile &)>/dev/null 2>&1 &) ; tail --follow=name logfile
|
||||||
|
@ -1414,7 +1402,7 @@ fn test_follow_name_move() {
|
||||||
fn test_follow_inotify_only_regular() {
|
fn test_follow_inotify_only_regular() {
|
||||||
// The GNU test inotify-only-regular.sh uses strace to ensure that `tail -f`
|
// The GNU test inotify-only-regular.sh uses strace to ensure that `tail -f`
|
||||||
// doesn't make inotify syscalls and only uses inotify for regular files or fifos.
|
// doesn't make inotify syscalls and only uses inotify for regular files or fifos.
|
||||||
// We just check if tailing a character device has the same behaviour than GNU's tail.
|
// We just check if tailing a character device has the same behavior as GNU's tail.
|
||||||
|
|
||||||
let ts = TestScenario::new(util_name!());
|
let ts = TestScenario::new(util_name!());
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue