@@ -33,19 +33,20 @@ impl WatcherRx {
3333 }
3434
3535 /// Wrapper for `notify::Watcher::watch` to also add the parent directory of `path` if necessary.
36- /// When using polling, we watch the file directly; when using inotify, we watch the parent directory.
37- fn watch_with_parent ( & mut self , path : & Path , #[ cfg_attr( not( target_os = "linux" ) , allow( unused_variables) ) ] use_polling : bool ) -> UResult < ( ) > {
36+ /// When using polling OR --follow=descriptor, watch the file directly.
37+ /// When using inotify with --follow=name, watch the parent directory.
38+ fn watch_with_parent ( & mut self , path : & Path , #[ cfg_attr( not( target_os = "linux" ) , allow( unused_variables) ) ] use_polling : bool , #[ cfg_attr( not( target_os = "linux" ) , allow( unused_variables) ) ] follow_name : bool ) -> UResult < ( ) > {
3839 let mut path = path. to_owned ( ) ;
3940 #[ cfg( target_os = "linux" ) ]
40- if path. is_file ( ) && !use_polling {
41+ if path. is_file ( ) && !use_polling && follow_name {
4142 /*
42- NOTE: Using the parent directory instead of the file is a workaround for inotify.
43+ NOTE: Using the parent directory instead of the file is a workaround for inotify with --follow=name .
4344 This workaround follows the recommendation of the notify crate authors:
4445 > On some platforms, if the `path` is renamed or removed while being watched, behavior may
4546 > be unexpected. See discussions in [#165] and [#166]. If less surprising behavior is wanted
4647 > one may non-recursively watch the _parent_ directory as well and manage related events.
47- NOTE: This only applies to InotifyWatcher. PollWatcher sends events with the file path,
48- not the parent path, so we should watch the file directly when polling .
48+ NOTE: This only applies to InotifyWatcher with --follow=name. For --follow=descriptor or
49+ PollWatcher, we watch the file directly.
4950 */
5051 if let Some ( parent) = path. parent ( ) {
5152 // clippy::assigning_clones added with Rust 1.78
@@ -276,6 +277,8 @@ impl Observer {
276277 }
277278
278279 fn init_files ( & mut self , inputs : & Vec < Input > ) -> UResult < ( ) > {
280+ let use_polling = self . use_polling ;
281+ let follow_name = self . follow_name ( ) ;
279282 if let Some ( watcher_rx) = & mut self . watcher_rx {
280283 for input in inputs {
281284 match input. kind ( ) {
@@ -292,7 +295,7 @@ impl Observer {
292295
293296 if path. is_tailable ( ) {
294297 // Add existing regular files to `Watcher` (InotifyWatcher).
295- watcher_rx. watch_with_parent ( & path, self . use_polling ) ?;
298+ watcher_rx. watch_with_parent ( & path, use_polling, follow_name ) ?;
296299 } else if !path. is_orphan ( ) {
297300 // If `path` is not a tailable file, add its parent to `Watcher`.
298301 watcher_rx
@@ -477,8 +480,10 @@ impl Observer {
477480 ) ;
478481
479482 // Unwatch old path and watch new path
483+ let use_polling = self . use_polling ;
484+ let follow_name = self . follow_name ( ) ;
480485 let _ = self . watcher_rx . as_mut ( ) . unwrap ( ) . unwatch ( event_path) ;
481- self . watcher_rx . as_mut ( ) . unwrap ( ) . watch_with_parent ( new_path, self . use_polling ) ?;
486+ self . watcher_rx . as_mut ( ) . unwrap ( ) . watch_with_parent ( new_path, use_polling, follow_name ) ?;
482487 }
483488 }
484489 _ => { }
@@ -525,11 +530,13 @@ pub fn follow(mut observer: Observer, settings: &Settings) -> UResult<()> {
525530 observer. files . update_metadata ( new_path, Some ( md) ) ;
526531 observer. files . update_reader ( new_path) ?;
527532 _read_some = observer. files . tail_file ( new_path, settings. verbose ) ?;
533+ let use_polling = observer. use_polling ;
534+ let follow_name = observer. follow_name ( ) ;
528535 observer
529536 . watcher_rx
530537 . as_mut ( )
531538 . unwrap ( )
532- . watch_with_parent ( new_path, observer . use_polling ) ?;
539+ . watch_with_parent ( new_path, use_polling, follow_name ) ?;
533540 }
534541 }
535542 }
0 commit comments