@@ -330,20 +330,24 @@ fn prepare_tokio_command(
330330 prepare_sandbox_dirs ( cwd) ;
331331 }
332332
333- if let Some ( launcher) = build_linux_sandbox_command ( command, cwd, sandbox_status) {
334- let mut prepared = TokioCommand :: new ( launcher. program ) ;
335- prepared. args ( launcher. args ) ;
336- prepared. current_dir ( cwd) ;
337- prepared. envs ( launcher. env ) ;
338- return prepared;
339- }
333+ let mut prepared =
334+ if let Some ( launcher) = build_linux_sandbox_command ( command, cwd, sandbox_status) {
335+ let mut cmd = TokioCommand :: new ( launcher. program ) ;
336+ cmd. args ( launcher. args ) ;
337+ cmd. envs ( launcher. env ) ;
338+ cmd
339+ } else {
340+ let mut cmd = TokioCommand :: new ( "sh" ) ;
341+ cmd. arg ( "-lc" ) . arg ( command) ;
342+ if sandbox_status. filesystem_active {
343+ cmd. env ( "HOME" , cwd. join ( ".sandbox-home" ) ) ;
344+ cmd. env ( "TMPDIR" , cwd. join ( ".sandbox-tmp" ) ) ;
345+ }
346+ cmd
347+ } ;
340348
341- let mut prepared = TokioCommand :: new ( "sh" ) ;
342- prepared. arg ( "-lc" ) . arg ( command) . current_dir ( cwd) ;
343- if sandbox_status. filesystem_active {
344- prepared. env ( "HOME" , cwd. join ( ".sandbox-home" ) ) ;
345- prepared. env ( "TMPDIR" , cwd. join ( ".sandbox-tmp" ) ) ;
346- }
349+ prepared. current_dir ( cwd) ;
350+ prepared. stdin ( Stdio :: null ( ) ) ;
347351 prepared
348352}
349353
@@ -419,6 +423,27 @@ mod tests {
419423 assert_eq ! ( structured[ 0 ] [ "event" ] , "test.hung" ) ;
420424 assert_eq ! ( structured[ 0 ] [ "data" ] [ "provenance" ] , "bash.timeout" ) ;
421425 }
426+
427+ #[ test]
428+ fn prevents_stdin_hangs_by_redirecting_to_null ( ) {
429+ let output = execute_bash ( BashCommandInput {
430+ command : String :: from ( "cat" ) ,
431+ timeout : Some ( 2_000 ) ,
432+ description : None ,
433+ run_in_background : Some ( false ) ,
434+ dangerously_disable_sandbox : Some ( true ) ,
435+ namespace_restrictions : None ,
436+ isolate_network : None ,
437+ filesystem_mode : None ,
438+ allowed_mounts : None ,
439+ } )
440+ . expect ( "bash command should execute cleanly" ) ;
441+
442+ assert ! (
443+ !output. interrupted,
444+ "Command hung and was cut off by the timeout!"
445+ ) ;
446+ }
422447}
423448
424449/// Maximum output bytes before truncation (16 KiB, matching upstream).
0 commit comments