@@ -1436,6 +1436,51 @@ fn test_retry6() {
14361436 . stderr_is ( expected_stderr) ;
14371437}
14381438
1439+ #[ test]
1440+ #[ cfg( not( target_os = "windows" ) ) ] // Fails on Windows: ReadDirectoryChangesW behavior differs from Unix inotify/kqueue
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/kqueue watches entire directories, not just specific files.
1446+ //
1447+ // Note: Excluded on Windows because the test fails - appended content is not detected
1448+ // (expects "initial\nappended\n" but gets only "initial\n"). This is due to differences
1449+ // in how Windows' ReadDirectoryChangesW handles file watching compared to Unix systems.
1450+
1451+ let ts = TestScenario :: new ( util_name ! ( ) ) ;
1452+ let at = & ts. fixtures ;
1453+
1454+ // Create a directory with an initial tracked file
1455+ at. mkdir ( "watched_dir" ) ;
1456+ at. write ( "watched_dir/tracked.txt" , "initial\n " ) ;
1457+
1458+ let mut p = ts
1459+ . ucmd ( )
1460+ . arg ( "--follow=descriptor" )
1461+ . arg ( "watched_dir/tracked.txt" )
1462+ . run_no_wait ( ) ;
1463+
1464+ let delay = 1000 ;
1465+ p. make_assertion_with_delay ( delay) . is_alive ( ) ;
1466+
1467+ // Create a new untracked file in the same directory
1468+ // This generates a file system event that reaches handle_event()
1469+ at. write ( "watched_dir/untracked.txt" , "should be ignored\n " ) ;
1470+ p. delay ( delay) ;
1471+
1472+ // Append to the tracked file to verify tail still works correctly
1473+ at. append ( "watched_dir/tracked.txt" , "appended\n " ) ;
1474+ p. delay ( delay) ;
1475+
1476+ // Verify: No crash, correct output for tracked file only, no error messages
1477+ p. kill ( )
1478+ . make_assertion ( )
1479+ . with_all_output ( )
1480+ . stdout_is ( "initial\n appended\n " )
1481+ . no_stderr ( ) ;
1482+ }
1483+
14391484#[ test]
14401485#[ cfg( all(
14411486 not( target_vendor = "apple" ) ,
0 commit comments