mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-15 04:32:24 +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:
parent
4856847631
commit
2bc1d814c9
3 changed files with 64 additions and 8 deletions
3
NEWS
3
NEWS
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
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(sferr==SH_EXITSIG)
|
||||
{
|
||||
/* Ctrl+C with SIGINT ignored */
|
||||
sfputc(sfstderr,'\n');
|
||||
continue;
|
||||
}
|
||||
else if(job_close(shp)<0)
|
||||
continue;
|
||||
}
|
||||
if(errno==0 && sferror(iop) && --maxtry>0)
|
||||
if(errno==0 && sferr && --maxtry>0)
|
||||
{
|
||||
sfclrlock(iop);
|
||||
sfclrerr(iop);
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in a new issue