diff --git a/src/cmd/ksh93/bltins/trap.c b/src/cmd/ksh93/bltins/trap.c index 974ac5de4e97..adc58b477cc3 100644 --- a/src/cmd/ksh93/bltins/trap.c +++ b/src/cmd/ksh93/bltins/trap.c @@ -127,6 +127,14 @@ int b_trap(int argc,char *argv[],Shbltin_t *context) shp->trapnote |= SH_SIGTRAP; else shp->trapnote = 0; + + } + if(sig == SH_ERRTRAP) + { + if(clear) + shp->errtrap = 0; + else if(!shp->fn_depth || shp->end_fn) + shp->errtrap = 1; } continue; } @@ -144,6 +152,8 @@ int b_trap(int argc,char *argv[],Shbltin_t *context) else if(clear) { sh_sigclear(sig); + if(sig == 0) + shp->exittrap = 0; if(dflag) signal(sig,SIG_DFL); } @@ -156,6 +166,8 @@ int b_trap(int argc,char *argv[],Shbltin_t *context) shp->st.trapcom[sig] = (shp->sigflag[sig]&SH_SIGOFF) ? Empty : strdup(action); if(arg && arg != Empty) free(arg); + if(sig == 0 && (!shp->fn_depth || shp->end_fn)) + shp->exittrap = 1; } } } diff --git a/src/cmd/ksh93/include/defs.h b/src/cmd/ksh93/include/defs.h index e641d99246d4..5332ec3bdb4d 100644 --- a/src/cmd/ksh93/include/defs.h +++ b/src/cmd/ksh93/include/defs.h @@ -272,7 +272,10 @@ struct shared Namfun_t nvfun; \ char *mathnodes; \ char *bltin_dir; \ - struct Regress_s*regress; + struct Regress_s*regress; \ + char exittrap; \ + char errtrap; \ + char end_fn; #include diff --git a/src/cmd/ksh93/sh/init.c b/src/cmd/ksh93/sh/init.c index 99d388e2e312..c81f0b7e476e 100644 --- a/src/cmd/ksh93/sh/init.c +++ b/src/cmd/ksh93/sh/init.c @@ -1479,6 +1479,9 @@ Shell_t *sh_init(register int argc,register char *argv[], Shinit_f userinit) #endif if(shp->userinit=userinit) (*userinit)(shp, 0); + shp->exittrap = 0; + shp->errtrap = 0; + shp->end_fn = 0; return(shp); } @@ -1580,6 +1583,9 @@ int sh_reinit(char *argv[]) shp->inpipe = shp->outpipe = 0; job_clear(); job.in_critical = 0; + shp->exittrap = 0; + shp->errtrap = 0; + shp->end_fn = 0; /* update ${.sh.pid}, $$, $PPID */ shgd->current_pid = shgd->pid = getpid(); shgd->ppid = getppid(); diff --git a/src/cmd/ksh93/sh/main.c b/src/cmd/ksh93/sh/main.c index 7b6ab42c03dd..b81d764f142b 100644 --- a/src/cmd/ksh93/sh/main.c +++ b/src/cmd/ksh93/sh/main.c @@ -455,6 +455,9 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno) error_info.line = 1; shp->inlineno = 1; shp->binscript = 0; + shp->exittrap = 0; + shp->errtrap = 0; + shp->end_fn = 0; if(sfeof(iop)) goto eof_or_error; /* command loop */ diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c index 11ca91cc9da5..f34fb5e1b419 100644 --- a/src/cmd/ksh93/sh/xec.c +++ b/src/cmd/ksh93/sh/xec.c @@ -987,6 +987,8 @@ int sh_exec(register const Shnode_t *t, int flags) shp->exitval=0; shp->lastsig = 0; shp->lastpath = 0; + if(shp->exittrap || shp->errtrap) + execflg = 0; switch(type&COMMSK) { case TCOM: @@ -3119,6 +3121,8 @@ int sh_funscope(int argn, char *argv[],int(*fun)(void*),void *arg,int execflg) nv_putval(SH_PATHNAMENOD,shp->st.filename,NV_NOFREE); nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE); } + if((execflg & sh_state(SH_NOFORK))) + shp->end_fn = 1; jmpval = sigsetjmp(buffp->buff,0); if(jmpval == 0) { @@ -3166,6 +3170,7 @@ int sh_funscope(int argn, char *argv[],int(*fun)(void*),void *arg,int execflg) shp->st = *prevscope; shp->topscope = (Shscope_t*)prevscope; nv_getval(sh_scoped(shp,IFSNOD)); + shp->end_fn = 0; if(nsig) { for (isig = 0; isig < nsig; ++isig) diff --git a/src/cmd/ksh93/tests/io.sh b/src/cmd/ksh93/tests/io.sh index 037ace820f0a..8cecc7ae8a70 100755 --- a/src/cmd/ksh93/tests/io.sh +++ b/src/cmd/ksh93/tests/io.sh @@ -649,5 +649,53 @@ err=$( ((!(e = $?))) || err_exit 'crash on null-command redirection with DEBUG trap' \ "(got status $e$( ((e>128)) && print -n / && kill -l "$e"), $(printf %q "$got"))" +# ====== +# stdout was misdirected if an EXIT/ERR trap handler was defined in a -c script +# https://github.com/att/ast/issues/36 +exp=$'exit to stdout\ntrap to stdout' +exp2=$'exit to file\ntrap to file' +got=$(export tmp; "$SHELL" -ec \ +' function log + { + echo "$* to stdout" + echo "$* to file" >> $tmp/ast36_a.test.log + } + function test_exit + { + log trap + } + trap test_exit EXIT + log exit +') +[[ $got == "$exp" ]] || err_exit 'stdout misdirected to file with EXIT/ERR trap defined (1)' \ + "(expected $(printf %q "$exp"), got $(printf %q "$got"))" +[[ $(< $tmp/ast36_a.test.log) == "$exp2" ]] || err_exit 'stdout not correctly redirected to file with EXIT/ERR trap defined (1)' \ + "(expected $(printf %q "$exp2"), wrote $(printf %q "$(< $tmp/ast36_a.test.log)"))" + +exp=$'trap to stdout\nexit to stdout' +exp2=$'trap to file\nexit to file' +got=$(export tmp; "$SHELL" -ec \ +' function log + { + echo "$* to stdout" + echo "$* to file" >> $tmp/ast36_b.test.log + } + function test_exit + { + trap test_exittrap EXIT + log trap + } + function test_exittrap + { + log exit + } + test_exit +') +[[ $got == "$exp" ]] || err_exit 'stdout misdirected to file with EXIT/ERR trap defined (2)' \ + "(expected $(printf %q "$exp"), got $(printf %q "$got"))" +[[ $(< $tmp/ast36_b.test.log) == "$exp2" ]] || err_exit 'stdout not correctly redirected to file with EXIT/ERR trap defined (2)' \ + "(expected $(printf %q "$exp2"), wrote $(printf %q "$(< $tmp/ast36_b.test.log)"))" + + # ====== exit $((Errors<125?Errors:125))