Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Interactive: Avoid losing the job after suspending a subshell
Reproducer: run vi in a subshell: $ (vi) vi opens; now press Ctrl+Z to suspend. The output is as expected: [2] + Stopped (vi) …but the exit status is 18 (SIGTSTP's signal number) instead of 0. Now do: $ fg (vi) $ The exit status is 18 again, vi is not resumed, and the job is lost. You have to find vi's pid manually using ps and kill it. Forking all non-command substitution subshells invoked from the interactive main shell is the only reliable and effective fix I've found. I've tried to fork the subshell conditionally in every other remotely plausible place I can think of in fault.c and xec.c, but I can't get anything to work properly. If anyone can get this to work without forking as much (or at all), please do submit a patch or PR that supersedes this fix. At least subshells of subshells don't need to fork, so the performance impact can be limited. Plus, it's not as if most people need maximum speed on the interactive command line. Scripts (including login/profile scripts) are not affected at all. Command substitutions can be handled differently. My testing shows that all shells except ksh93 simply block SIGTSTP (the ^Z signal) while they run. We should do the same, so they don't need to fork. NOTE for any backporters: the subshell.c and fault.c changes depend on commits 35b0262 and 48ba696 to work correctly. src/cmd/ksh93/sh/subshell.c: sh_subshell(): - If the interactive shell state bit is on, then before executing the subshell's code: - for command substitutions, block SIGTSTP; - for other subshells, fork. - For command substitutions, release SIGTSTP if the interactive shell state bit was on upon invoking the subshell. src/cmd/ksh93/sh/fault.c: - Instead of checking for a virtual subshell, check the shell's interactive state bit to decide whether to handle SIGTSTP, as that is only turned on in the interactive main shell. src/cmd/ksh93/sh/main.c: sh_main(): - To avoid bugs, ignore SIGTSTP while running profile scripts. Blocking it doesn't work because delaying it until after sigrelease() will cause a crash. Thanks to @JohnoKing for this. - While we're here, prevent a possible overflow of the 'beenhere' static char variable by only incrementing it once. Co-authored-by: Johnothan King <[email protected]> Resolves: #390
- Loading branch information