diff --git a/NEWS b/NEWS index 3baa35769..63cd428ac 100644 --- a/NEWS +++ b/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 diff --git a/src/cmd/ksh93/sh/main.c b/src/cmd/ksh93/sh/main.c index 6abc1ca4c..0ce2d81a9 100644 --- a/src/cmd/ksh93/sh/main.c +++ b/src/cmd/ksh93/sh/main.c @@ -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); diff --git a/src/cmd/ksh93/tests/pty.sh b/src/cmd/ksh93/tests/pty.sh index 9883bfb9b..0f07073d8 100755 --- a/src/cmd/ksh93/tests/pty.sh +++ b/src/cmd/ksh93/tests/pty.sh @@ -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))