Skip to content

Change SIGINT special handling#282

Open
jpco wants to merge 2 commits into
wryun:masterfrom
jpco:resigint
Open

Change SIGINT special handling#282
jpco wants to merge 2 commits into
wryun:masterfrom
jpco:resigint

Conversation

@jpco

@jpco jpco commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

This PR is related to #281. It changes how the SIGINT signal is handled by es.

  1. If a SIGINT comes in while the shell is waiting for a forkexec()ed child, and that child exits with WTERMSIG() != SIGINT, then throw away the signal and do not raise an exception.

  2. Remove sig_special, sigint_newline, and the .sigint syntax for $signals; default sigint handling to sig_catch where previously it would have been sig_special.

  3. In the %interactive-loop exception handler, echo a newline for sigint, sigtstp, and sigquit signal exceptions.

The first change makes es into a "WCE" shell according to https://www.cons.org/cracauer/sigint.html. The idea is that if the shell is waiting for a child process, and that child process is in the same foregrounded process group as the shell (which is generally always true given es has no job control), and if the shell receives a SIGINT, then the child probably did too, and it should be up to the child whether the SIGINT should stop everything or not.

The second and third changes modify where the special \n for ^C happens, from special-cased internal code to a small bit of if logic in %interactive-loop (making the newline only happen in interactive shells). This improves the user-visible behavior; for example, with es at head:

; es -c 'es -c ''sleep 1'''
^C


; 

and with this PR:

; es -c 'es -c ''sleep 1'''
^C
; 

For completeness, we also include sigtstp and sigquit in the special newline handling in %interactive-loop, given they're also terminal-generated signals.

This is backwards-incompatible, of course, and it's debatable whether the "WCE" behavior is actually what we want (for example, the zsh folks intentionally don't go with WCE), but it seems like it nicely kills a few birds with one stone: we remove the special one-off .sigint mechanism AND get better ^C newline printing AND (arguably) get better handling of SIGINT while waiting for child processes.

jpco added 2 commits June 17, 2026 11:18
- Remove sig_special, sigint_newline, and the `.signal' syntax for
  $signals
- Ignore SIGINT entirely if our child did not exit with a SIGINT status
- Print \n in %interactive-loop when catching SIG^(INT TSTP QUIT)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant