1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

Do not exit shell on Ctrl+C with SIGINT ignored (re: 7e5fd3e9)

The killpg(getpgrp(),SIGINT) call added to ed_getchar() in that
commit caused the interactive shell to exit on ^C even if SIGINT is
being ignored. We cannot revert or remove that call without
breaking job control. This commit applies a new fix instead.

Reproducers fixed by this commit:

  SIGINT ignored by child:

    $ PS1='childshell$ ' ksh
    childshell$ trap '' INT
    childshell$ (press Ctrl+C)
    $

  SIGINT ignored by parent:

    $ (trap '' INT; ENV=/./dev/null PS1='childshell$ ' ksh)
    childshell$ (press Ctrl+C)
    $

  SIGINT ignored by parent, trapped in child:

    $ (trap '' INT; ENV=/./dev/null PS1='childshell$ ' ksh)
    childshell$ trap 'echo test' INT
    childshell$ (press Ctrl+C)
    $

I've experimentally determined that, under these conditions, the
SFIO stream error state is set to 256 == 0400 == SH_EXITSIG.

src/cmd/ksh93/sh/main.c: exfile():
- On EOF or error, do not return (exiting the shell) if the shell
  state is interactive and if sferror(iop)==SH_EXITSIG.
- Refactor that block a little to make the new check fit in nicely.

src/cmd/ksh93/tests/pty.sh:
- Test the above three reproducers.

Fixes: https://github.com/ksh93/ksh/issues/343
This commit is contained in:
Martijn Dekker 2021-12-16 16:40:42 +01:00
parent 4856847631
commit 2bc1d814c9
3 changed files with 64 additions and 8 deletions

View file

@ -948,5 +948,47 @@ w : ..\t
r : \.\./\r\n$
!
# err_exit #
tst $LINENO <<"!"
L Ctrl+C with SIGINT ignored
# https://github.com/ksh93/ksh/issues/343
d 15
# SIGINT ignored by child
p :test-1:
w PS1=':child-!: ' "$SHELL"
p :child-1:
w trap '' INT
p :child-2:
c \\\cC
r :child-2:
w echo "OK $PS1"
u ^OK :child-!: \r\n$
w exit
# SIGINT ignored by parent
p :test-2:
w (trap '' INT; ENV=/./dev/null PS1=':child-!: ' "$SHELL")
p :child-1:
c \\\cC
r :child-1:
w echo "OK $PS1"
u ^OK :child-!: \r\n$
w exit
# SIGINT ignored by parent, trapped in child
p :test-3:
w (trap '' INT; ENV=/./dev/null PS1=':child-!: ' "$SHELL")
p :child-1:
w trap 'echo test' INT
p :child-2:
c \\\cC
r :child-2:
w echo "OK $PS1"
u ^OK :child-!: \r\n$
w exit
!
# ======
exit $((Errors<125?Errors:125))