Skip to content

Commit

Permalink
Do not exit shell on Ctrl+C with SIGINT ignored (re: 7e5fd3e)
Browse files Browse the repository at this point in the history
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: #343
  • Loading branch information
McDutchie committed Dec 16, 2021
1 parent 0508608 commit 55dc80c
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 8 deletions.
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ Any uppercase BUG_* names are modernish shell bug IDs.
command to: basename, cat, cp, cut, dirname, getconf, ln, mktemp, mv.
Add /opt/ast/bin to your $PATH to use these. Type 'cp --man', etc. for info.

- A bug introduced on 2020-09-17 was fixed that caused interactive ksh to exit
if Ctrl+C was pressed while SIGINT was being ignored (as in "trap '' INT").

2021-12-13:

- Fixed a bug introduced on 2020-08-09 that prevented '.' and '..' from
Expand Down
27 changes: 19 additions & 8 deletions src/cmd/ksh93/sh/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,20 +535,31 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno)
errno = 0;
if(tdone || !sfreserve(iop,0,0))
{
int sferr;
eof_or_error:
if(sh_isstate(SH_INTERACTIVE) && !sferror(iop))
sferr = sferror(iop);
if(sh_isstate(SH_INTERACTIVE))
{
if(--maxtry>0 && sh_isoption(SH_IGNOREEOF) &&
!sferror(sfstderr) && (shp->fdstatus[fno]&IOTTY))
if(!sferr)
{
sfclrerr(iop);
errormsg(SH_DICT,0,e_logout);
continue;
if(--maxtry>0 && sh_isoption(SH_IGNOREEOF)
&& !sferror(sfstderr) && (shp->fdstatus[fno]&IOTTY))
{
sfclrerr(iop);
errormsg(SH_DICT,0,e_logout);
continue;
}
else if(job_close(shp)<0)
continue;
}
else if(job_close(shp)<0)
else if(sferr==SH_EXITSIG)
{
/* Ctrl+C with SIGINT ignored */
sfputc(sfstderr,'\n');
continue;
}
}
if(errno==0 && sferror(iop) && --maxtry>0)
if(errno==0 && sferr && --maxtry>0)
{
sfclrlock(iop);
sfclrerr(iop);
Expand Down
42 changes: 42 additions & 0 deletions src/cmd/ksh93/tests/pty.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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))

0 comments on commit 55dc80c

Please sign in to comment.