File tree Expand file tree Collapse file tree 2 files changed +64
-5
lines changed
Expand file tree Collapse file tree 2 files changed +64
-5
lines changed Original file line number Diff line number Diff line change @@ -65,11 +65,24 @@ impl ShellCommand for ExecutableCommand {
6565 loop {
6666 tokio:: select! {
6767 result = child. wait( ) => match result {
68- Ok ( status) => return ExecuteResult :: Continue (
69- status. code( ) . unwrap_or( 1 ) ,
70- Vec :: new( ) ,
71- Vec :: new( ) ,
72- ) ,
68+ Ok ( status) => {
69+ #[ cfg( unix) ]
70+ let exit_code = {
71+ use std:: os:: unix:: process:: ExitStatusExt ;
72+ status. code( ) . unwrap_or_else( || {
73+ // Process was terminated by a signal, return 128 + signal_number per POSIX
74+ status. signal( ) . map( |sig| 128 + sig) . unwrap_or( 1 )
75+ } )
76+ } ;
77+ #[ cfg( not( unix) ) ]
78+ let exit_code = status. code( ) . unwrap_or( 1 ) ;
79+
80+ return ExecuteResult :: Continue (
81+ exit_code,
82+ Vec :: new( ) ,
83+ Vec :: new( ) ,
84+ ) ;
85+ }
7386 Err ( err) => {
7487 let _ = stderr. write_line( & format!( "{}" , err) ) ;
7588 return ExecuteResult :: from_exit_code( 1 ) ;
Original file line number Diff line number Diff line change @@ -1631,3 +1631,49 @@ fn no_such_file_error_text() -> &'static str {
16311631 "No such file or directory (os error 2)"
16321632 }
16331633}
1634+
1635+ #[ tokio:: test]
1636+ #[ cfg( unix) ]
1637+ async fn signal_exit_codes ( ) {
1638+ // Test SIGPIPE exit code (128 + 13 = 141)
1639+ TestBuilder :: new ( )
1640+ . command ( "sh -c 'kill -PIPE $$'" )
1641+ . assert_exit_code ( 141 )
1642+ . run ( )
1643+ . await ;
1644+
1645+ // Test SIGTERM exit code (128 + 15 = 143)
1646+ TestBuilder :: new ( )
1647+ . command ( "sh -c 'kill -TERM $$'" )
1648+ . assert_exit_code ( 143 )
1649+ . run ( )
1650+ . await ;
1651+
1652+ // Test SIGINT exit code (128 + 2 = 130)
1653+ TestBuilder :: new ( )
1654+ . command ( "sh -c 'kill -INT $$'" )
1655+ . assert_exit_code ( 130 )
1656+ . run ( )
1657+ . await ;
1658+
1659+ // Test SIGKILL exit code (128 + 9 = 137)
1660+ TestBuilder :: new ( )
1661+ . command ( "sh -c 'kill -KILL $$'" )
1662+ . assert_exit_code ( 137 )
1663+ . run ( )
1664+ . await ;
1665+ }
1666+
1667+ #[ tokio:: test]
1668+ #[ cfg( unix) ]
1669+ async fn sigpipe_from_pipeline ( ) {
1670+ // Test that SIGPIPE from a closed pipe doesn't cause issues
1671+ // and the pipeline completes successfully
1672+ // `yes` outputs infinite "y\n" until SIGPIPE, `head -n 1` reads one line
1673+ TestBuilder :: new ( )
1674+ . command ( "yes | head -n 1" )
1675+ . assert_stdout ( "y\n " )
1676+ . assert_exit_code ( 0 )
1677+ . run ( )
1678+ . await ;
1679+ }
You can’t perform that action at this time.
0 commit comments