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