Skip to content

Commit

Permalink
Allow kill built-in to terminate interactive shell
Browse files Browse the repository at this point in the history
Reproducer:

  $ kill -s HUP $$
  $

Since the signal is not SIGTERM or SIGQUIT and is not trapped, even
the interactive shell should terminate, but ksh happily returns to
the prompt. The exit status reflects that SIGHUP was sent, but the
interactive shell fails to exit when the 'kill' built-in is used.
Oddly enough, the external 'kill' command works fine:

  $ command -x kill -s HUP $$
  Hangup

On every other shell, the kill built-in also works as expected.

Analysis: in sh_fault(), when processing a signal flagged with
SH_DONE (terminates the shell by default), the mode flag in
sh.jmplist (the longjmp return stack) is set to SH_JMPSUB or
SH_JMPFUN, values used for returning from virtual subshells and
ksh-style functions, relatively. But those will not cause the shell
to exit as expected. For that, we need SH_JMPEXIT (see main.c line
628-629).

src/cmd/ksh93/sh/fault.c: sh_fault():
- Make sure the SH_JMPEXIT longjmp return mode is used when the
  shell is in the SH_INTERACTIVE state. (Note that, as of 48ba696,
  this state bit is alwayas off in subshells, so this change does
  not affect subshells of interactive shells.)
  • Loading branch information
McDutchie committed Jan 12, 2024
1 parent c7e1225 commit e4cfcca
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 1 deletion.
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ Uppercase BUG_* IDs are shell bug IDs as used by the Modernish shell library.
causing a stopped process to be incorrectly resumed upon sending it any
signal and causing any SIGCONT trap handler to be incorrectly triggered.

- Fixed: the 'kill' built-in was not able to terminate an interactive shell
by sending a signal such as SIGHUP to its own shell (e.g. kill -s HUP $$).

2024-01-05:

- Fixed a potential crash on pressing Ctrl+C on the command line while
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/sh/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ void sh_fault(int sig)
sigrelease(sig);
if(pp->mode != SH_JMPSUB)
{
if(pp->mode < SH_JMPSUB)
if(pp->mode < SH_JMPSUB && !sh_isstate(SH_INTERACTIVE))
pp->mode = sh.subshell?SH_JMPSUB:SH_JMPFUN;
else
pp->mode = SH_JMPEXIT;
Expand Down
12 changes: 12 additions & 0 deletions src/cmd/ksh93/tests/pty.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1255,5 +1255,17 @@ w _ksh_93u_m_cmdcompl\t
r :test-2: _ksh_93u_m_cmdcomplete_test_ \r\n$
!

tst $LINENO <<"!"
L terminate interactive shell using the kill built-in
d 40
p :test-1:
w PS1=':child-!: ' "$SHELL"
p :child-1:
w kill -s HUP \$\$
r ^:child-1: kill -s HUP \$\$\r\n$
r ^Hangup\r\n$
!

# ======
exit $((Errors<125?Errors:125))

0 comments on commit e4cfcca

Please sign in to comment.