diff --git a/src/uu/tail/locales/en-US.ftl b/src/uu/tail/locales/en-US.ftl index 6d434ae9862..20ba82fd057 100644 --- a/src/uu/tail/locales/en-US.ftl +++ b/src/uu/tail/locales/en-US.ftl @@ -73,5 +73,6 @@ tail-no-files-remaining = no files remaining tail-become-inaccessible = has become inaccessible # Debug messages +tail-debug-using-blocking-mode = using blocking mode tail-debug-using-notification-mode = using notification mode tail-debug-using-polling-mode = using polling mode diff --git a/src/uu/tail/locales/fr-FR.ftl b/src/uu/tail/locales/fr-FR.ftl index 85d973571ae..67008ef7550 100644 --- a/src/uu/tail/locales/fr-FR.ftl +++ b/src/uu/tail/locales/fr-FR.ftl @@ -70,3 +70,8 @@ tail-giving-up-on-this-name = ; abandon de ce nom tail-stdin-header = entrée standard tail-no-files-remaining = aucun fichier restant tail-become-inaccessible = est devenu inaccessible + +# Messages de débogage +tail-debug-using-blocking-mode = utilisation du mode bloquant +tail-debug-using-notification-mode = utilisation du mode notification +tail-debug-using-polling-mode = utilisation du mode sondage diff --git a/src/uu/tail/src/follow/watch.rs b/src/uu/tail/src/follow/watch.rs index 06a355b2217..c1fa3775ec7 100644 --- a/src/uu/tail/src/follow/watch.rs +++ b/src/uu/tail/src/follow/watch.rs @@ -381,6 +381,14 @@ impl Observer { } self.files.update_metadata(event_path, Some(new_md)); } else if event_path.is_symlink() && settings.retry { + if let Some(old_md) = self.files.get_mut_metadata(event_path) { + if old_md.is_tailable() && self.files.get(event_path).reader.is_some() { + show_error!( + "{}", + translate!("tail-status-file-became-inaccessible", "file" => display_name.quote(), "become_inaccessible" => translate!("tail-become-inaccessible"), "no_such_file" => translate!("tail-no-such-file-or-directory")) + ); + } + } self.files.reset_reader(event_path); self.orphans.push(event_path.clone()); } diff --git a/src/uu/tail/src/tail.rs b/src/uu/tail/src/tail.rs index ad568db7628..87c9099e309 100644 --- a/src/uu/tail/src/tail.rs +++ b/src/uu/tail/src/tail.rs @@ -22,7 +22,7 @@ mod platform; pub mod text; pub use args::uu_app; -use args::{FilterMode, Settings, Signum, parse_args}; +use args::{FilterMode, FollowMode, Settings, Signum, parse_args}; use chunks::ReverseChunks; use follow::Observer; use memchr::{memchr_iter, memrchr_iter}; @@ -68,8 +68,14 @@ fn uu_tail(settings: &Settings) -> UResult<()> { // Print debug info about the follow implementation being used if settings.debug && settings.follow.is_some() { - if observer.use_polling { + let all_non_regular = settings + .inputs + .iter() + .all(|i| !matches!(i.kind(), InputKind::File(p) if p.is_file())); + if observer.use_polling || (all_non_regular && settings.follow == Some(FollowMode::Name)) { show_error!("{}", translate!("tail-debug-using-polling-mode")); + } else if all_non_regular { + show_error!("{}", translate!("tail-debug-using-blocking-mode")); } else { show_error!("{}", translate!("tail-debug-using-notification-mode")); } diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index f2875e7b1e3..8f466f07268 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -5133,6 +5133,50 @@ fn test_debug_flag_with_polling() { .stderr_contains("tail: using polling mode"); } +#[test] +#[cfg(target_os = "linux")] +fn test_debug_flag_blocking_mode_non_regular() { + let mut child = new_ucmd!() + .args(&["--debug", "-f", "/dev/null"]) + .run_no_wait(); + child.make_assertion_with_delay(500).is_alive(); + child + .kill() + .make_assertion() + .with_all_output() + .stderr_contains("tail: using blocking mode"); +} + +#[test] +#[cfg(target_os = "linux")] +fn test_debug_flag_polling_mode_non_regular_follow_name() { + let mut child = new_ucmd!() + .args(&["--debug", "-F", "/dev/null"]) + .run_no_wait(); + child.make_assertion_with_delay(500).is_alive(); + child + .kill() + .make_assertion() + .with_all_output() + .stderr_contains("tail: using polling mode"); +} + +#[test] +#[cfg(target_os = "linux")] +fn test_debug_flag_notification_mode_regular_follow_name() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + at.touch("f"); + + let mut child = ts.ucmd().args(&["--debug", "-F", "f"]).run_no_wait(); + child.make_assertion_with_delay(500).is_alive(); + child + .kill() + .make_assertion() + .with_all_output() + .stderr_contains("tail: using notification mode"); +} + #[test] #[cfg(target_os = "linux")] fn test_debug_flag_with_inotify() {