@@ -1436,6 +1436,47 @@ fn test_retry6() {
14361436 . stderr_is ( expected_stderr) ;
14371437}
14381438
1439+ #[ test]
1440+ #[ cfg( not( target_os = "windows" ) ) ]
1441+ fn test_follow_descriptor_untracked_file_in_watched_dir ( ) {
1442+ // Regression test for PR #9630
1443+ // Ensure that --follow=descriptor (without --retry) doesn't crash when a new
1444+ // untracked file is created in a watched directory.
1445+ // This can happen because inotify watches entire directories, not just specific files.
1446+
1447+ let ts = TestScenario :: new ( util_name ! ( ) ) ;
1448+ let at = & ts. fixtures ;
1449+
1450+ // Create a directory with an initial tracked file
1451+ at. mkdir ( "watched_dir" ) ;
1452+ at. write ( "watched_dir/tracked.txt" , "initial\n " ) ;
1453+
1454+ let mut p = ts
1455+ . ucmd ( )
1456+ . arg ( "--follow=descriptor" )
1457+ . arg ( "watched_dir/tracked.txt" )
1458+ . run_no_wait ( ) ;
1459+
1460+ let delay = 1000 ;
1461+ p. make_assertion_with_delay ( delay) . is_alive ( ) ;
1462+
1463+ // Create a new untracked file in the same directory
1464+ // This generates a file system event that reaches handle_event()
1465+ at. write ( "watched_dir/untracked.txt" , "should be ignored\n " ) ;
1466+ p. delay ( delay) ;
1467+
1468+ // Append to the tracked file to verify tail still works correctly
1469+ at. append ( "watched_dir/tracked.txt" , "appended\n " ) ;
1470+ p. delay ( delay) ;
1471+
1472+ // Verify: No crash, correct output for tracked file only, no error messages
1473+ p. kill ( )
1474+ . make_assertion ( )
1475+ . with_all_output ( )
1476+ . stdout_is ( "initial\n appended\n " )
1477+ . no_stderr ( ) ;
1478+ }
1479+
14391480#[ test]
14401481#[ cfg( all(
14411482 not( target_vendor = "apple" ) ,
0 commit comments