@@ -376,6 +376,16 @@ async fn redirect(mut input: impl AsyncRead + Unpin, to: String) {
376376 }
377377}
378378
379+ /// inotify reports our own `write_all` as `Modify(Data)`, so only a removal or a
380+ /// rename (logrotate's default mode) means the path no longer names our file.
381+ fn is_rotation ( kind : & notify:: EventKind ) -> bool {
382+ use notify:: event:: { EventKind , ModifyKind } ;
383+ matches ! (
384+ kind,
385+ EventKind :: Remove ( _) | EventKind :: Modify ( ModifyKind :: Name ( _) )
386+ )
387+ }
388+
379389async fn try_redirect ( input : & mut ( impl AsyncRead + Unpin ) , to : String ) -> Result < ( ) > {
380390 let dst_path = Path :: new ( & to) ;
381391 let dst_path_buf = dst_path. to_path_buf ( ) ;
@@ -386,9 +396,7 @@ async fn try_redirect(input: &mut (impl AsyncRead + Unpin), to: String) -> Resul
386396 notify:: recommended_watcher ( move |res : Result < notify:: Event , notify:: Error > | {
387397 if let Ok ( event) = res {
388398 // Check if the event affects our specific file
389- if ( event. kind . is_remove ( ) || event. kind . is_modify ( ) )
390- && event. paths . iter ( ) . any ( |p| p == & dst_path_buf)
391- {
399+ if is_rotation ( & event. kind ) && event. paths . iter ( ) . any ( |p| p == & dst_path_buf) {
392400 let _ = reopen_tx. blocking_send ( ( ) ) ;
393401 }
394402 }
@@ -438,3 +446,20 @@ async fn try_redirect(input: &mut (impl AsyncRead + Unpin), to: String) -> Resul
438446 }
439447 }
440448}
449+
450+ #[ cfg( test) ]
451+ mod log_rotation_tests {
452+ use super :: is_rotation;
453+ use notify:: event:: { DataChange , EventKind , ModifyKind , RemoveKind , RenameMode } ;
454+
455+ #[ test]
456+ fn only_a_removal_or_a_rename_is_a_rotation ( ) {
457+ assert ! ( is_rotation( & EventKind :: Remove ( RemoveKind :: File ) ) ) ;
458+ assert ! ( is_rotation( & EventKind :: Modify ( ModifyKind :: Name (
459+ RenameMode :: From
460+ ) ) ) ) ;
461+ assert ! ( !is_rotation( & EventKind :: Modify ( ModifyKind :: Data (
462+ DataChange :: Any
463+ ) ) ) ) ;
464+ }
465+ }
0 commit comments