@@ -521,11 +521,9 @@ async fn listen_ctrl_c_windows() {
521521/// Listens to all incoming signals and forwards them to the child process.
522522///
523523/// Signal forwarding follows UV's approach:
524- /// - In interactive mode (stdin is TTY), we pass our PGID with the signal.
525- /// If the child is in the same PGID, deno_task_shell skips forwarding because
526- /// the terminal driver already delivered the signal to the entire process group.
527- /// - In non-interactive mode, we always forward signals since there's no terminal
528- /// driver involved and `kill -INT <pid>` is the expected way to send signals.
524+ /// - SIGINT in interactive mode: Include PGID so deno_task_shell can skip
525+ /// forwarding if the child is in the same PGID (terminal already sent it).
526+ /// - All other signals: Always forward unconditionally.
529527///
530528/// Trade-off: `kill -INT <pixi>` won't work in interactive mode when the child
531529/// is in the same PGID. Use CTRL+C instead, or `kill -TERM` which always forwards.
@@ -555,9 +553,11 @@ async fn listen_and_forward_all_signals(kill_signal: KillSignal) {
555553 } ;
556554 let signal_kind = signo. into ( ) ;
557555 while let Some ( ( ) ) = stream. recv ( ) . await {
558- // In interactive mode, include our PGID so deno_task_shell
559- // can handle same-PGID scenarios (CTRL+C vs kill -INT)
560- if is_interactive {
556+ // Only SIGINT gets PGID-aware handling in interactive mode.
557+ // The terminal driver sends SIGINT to the process group on Ctrl+C,
558+ // so we skip forwarding if the child is in the same PGID.
559+ // All other signals are forwarded unconditionally.
560+ if is_interactive && signo == libc:: SIGINT {
561561 kill_signal. send_from_pgid ( signal_kind, our_pgid) ;
562562 } else {
563563 kill_signal. send ( signal_kind) ;
0 commit comments