diff --git a/src/uu/tail/README.md b/src/uu/tail/README.md index 94b6816af..52db8bdac 100644 --- a/src/uu/tail/README.md +++ b/src/uu/tail/README.md @@ -6,12 +6,20 @@ ### Flags with features -- [ ] `--max-unchanged-stats` : with `--follow=name`, reopen a FILE which has not changed size after N (default 5) iterations to see if it has been unlinked or renamed (this is the usual case of rotated log files). With `inotify`, this option is rarely useful. -- [ ] `--retry` : keep trying to open a file even when it is or becomes inaccessible; useful when follow‐ing by name, i.e., with `--follow=name` +- [x] fastpoll='-s.1 --max-unchanged-stats=1' + - [x] sub-second sleep interval e.g. `-s.1` + - [ ] `--max-unchanged-stats` (only meaningful with `--follow=name` `---disable-inotify`) +- [x] `---disable-inotify` (three hyphens is correct) +- [x] `--follow=name' +- [ ] `--retry' +- [ ] `-F' (same as `--follow=name` `--retry`) ### Others - [ ] 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: + - [ ] `--max-unchanged-stats` + - [ ] check whether process p is alive at least every number of seconds (relevant for `--pid`) ## Possible optimizations diff --git a/src/uu/tail/src/tail.rs b/src/uu/tail/src/tail.rs index b44dd11ea..5e3bc1a1d 100644 --- a/src/uu/tail/src/tail.rs +++ b/src/uu/tail/src/tail.rs @@ -62,6 +62,7 @@ pub mod options { pub static SLEEP_INT: &str = "sleep-interval"; pub static ZERO_TERM: &str = "zero-terminated"; pub static DISABLE_INOTIFY_TERM: &str = "disable-inotify"; + pub static MAX_UNCHANGED_STATS: &str = "max-unchanged-stats"; pub static ARG_FILES: &str = "files"; } @@ -79,6 +80,7 @@ enum FollowMode { struct Settings { mode: FilterMode, sleep_sec: Duration, + max_unchanged_stats: usize, beginning: bool, follow: Option, force_polling: bool, @@ -90,6 +92,7 @@ impl Default for Settings { Settings { mode: FilterMode::Lines(10, b'\n'), sleep_sec: Duration::from_secs_f32(1.0), + max_unchanged_stats: 5, beginning: false, follow: None, force_polling: false, @@ -121,6 +124,17 @@ pub fn uumain(args: impl uucore::Args) -> i32 { } } + if let Some(s) = matches.value_of(options::MAX_UNCHANGED_STATS) { + settings.max_unchanged_stats = match s.parse::() { + Ok(s) => s, + Err(_) => crash!( + 1, + "invalid maximum number of unchanged stats between opens: {}", + s.quote() + ), + } + } + if let Some(pid_str) = matches.value_of(options::PID) { if let Ok(pid) = pid_str.parse() { settings.pid = pid; @@ -307,6 +321,17 @@ pub fn uu_app() -> App<'static, 'static> { .long(options::SLEEP_INT) .help("Number or seconds to sleep between polling the file when running with -f"), ) + .arg( + Arg::with_name(options::MAX_UNCHANGED_STATS) + .takes_value(true) + .long(options::MAX_UNCHANGED_STATS) + .help( + "Reopen a FILE which has not changed size after N (default 5) iterations to \ + see if it has been unlinked or renamed (this is the usual case of rotated log \ + files); This option is meaningful only when polling \ + (i.e., with --disable-inotify) and when --follow=name.", + ), + ) .arg( Arg::with_name(options::verbosity::VERBOSE) .short("v") @@ -404,6 +429,11 @@ fn follow(readers: &mut Vec<(Box, &PathBuf, Option)>, set // pid is dead break; } + + // TODO: + // Implement `--max-unchanged-stats`, however right now we use the `PollWatcher` from the + // notify crate if `--disable-inotify` is selected. This means we cannot do any thing + // useful with `--max-unchanged-stats` here. } }