diff options
Diffstat (limited to 'usr/src/lib/libshell/common/sh/fault.c')
-rw-r--r-- | usr/src/lib/libshell/common/sh/fault.c | 67 |
1 files changed, 43 insertions, 24 deletions
diff --git a/usr/src/lib/libshell/common/sh/fault.c b/usr/src/lib/libshell/common/sh/fault.c index 60af63972d..fc90ad573e 100644 --- a/usr/src/lib/libshell/common/sh/fault.c +++ b/usr/src/lib/libshell/common/sh/fault.c @@ -1,7 +1,7 @@ /*********************************************************************** * * * This software is part of the ast package * -* Copyright (c) 1982-2008 AT&T Intellectual Property * +* Copyright (c) 1982-2009 AT&T Intellectual Property * * and is licensed under the * * Common Public License, Version 1.0 * * by AT&T Intellectual Property * @@ -98,7 +98,7 @@ void sh_fault(register int sig) } return; } - if(shp->subshell && sig!=SIGINT && sig!=SIGQUIT && sig!=SIGWINCH) + if(shp->subshell && sig!=SIGINT && sig!=SIGQUIT && sig!=SIGWINCH && sig!=SIGCONT) { shp->exitval = SH_EXITSIG|sig; sh_subfork(); @@ -141,7 +141,7 @@ void sh_fault(register int sig) } /* mark signal and continue */ shp->trapnote |= SH_SIGSET; - if(sig < shp->sigmax) + if(sig <= shp->sigmax) shp->sigflag[sig] |= SH_SIGSET; #if defined(VMFL) && (VMALLOC_VERSION>=20031205L) if(abortsig(sig)) @@ -186,7 +186,6 @@ void sh_fault(register int sig) #endif /* SIGTSTP */ } #ifdef ERROR_NOTIFY - /* This is obsolete */ if((error_info.flags&ERROR_NOTIFY) && shp->bltinfun) action = (*shp->bltinfun)(-sig,(char**)0,(void*)0); if(action>0) @@ -198,7 +197,7 @@ void sh_fault(register int sig) return; } shp->trapnote |= flag; - if(sig < shp->sigmax) + if(sig <= shp->sigmax) shp->sigflag[sig] |= flag; if(pp->mode==SH_JMPCMD && sh_isstate(SH_STOPOK)) { @@ -215,23 +214,28 @@ void sh_fault(register int sig) void sh_siginit(void *ptr) { Shell_t *shp = (Shell_t*)ptr; - register int sig, n=SIGTERM+1; + register int sig, n; register const struct shtable2 *tp = shtab_signals; sig_begin(); /* find the largest signal number in the table */ -#ifdef SIGRTMIN - shp->sigruntime[SH_SIGRTMIN] = SIGRTMIN; -#endif /* SIGRTMIN */ -#ifdef SIGRTMAX - shp->sigruntime[SH_SIGRTMAX] = SIGRTMAX; -#endif /* SIGRTMAX */ +#if defined(SIGRTMIN) && defined(SIGRTMAX) + if ((n = SIGRTMIN) > 0 && (sig = SIGRTMAX) > n && sig < SH_TRAP) + { + shp->sigruntime[SH_SIGRTMIN] = n; + shp->sigruntime[SH_SIGRTMAX] = sig; + } +#endif /* SIGRTMIN && SIGRTMAX */ + n = SIGTERM; while(*tp->sh_name) { - sig = tp->sh_number&((1<<SH_SIGBITS)-1); - if ((tp->sh_number>>SH_SIGBITS) & SH_SIGRUNTIME) - sig = shp->sigruntime[sig-1]; - if(sig>n && sig<SH_TRAP) - n = sig; + sig = (tp->sh_number&((1<<SH_SIGBITS)-1)); + if (!(sig-- & SH_TRAP)) + { + if ((tp->sh_number>>SH_SIGBITS) & SH_SIGRUNTIME) + sig = shp->sigruntime[sig]; + if(sig>n && sig<SH_TRAP) + n = sig; + } tp++; } shp->sigmax = n++; @@ -241,7 +245,7 @@ void sh_siginit(void *ptr) for(tp=shtab_signals; sig=tp->sh_number; tp++) { n = (sig>>SH_SIGBITS); - if((sig &= ((1<<SH_SIGBITS)-1)) > shp->sigmax) + if((sig &= ((1<<SH_SIGBITS)-1)) > (shp->sigmax+1)) continue; sig--; if(n&SH_SIGRUNTIME) @@ -291,7 +295,7 @@ void sh_sigdone(void) { register int flag, sig = sh.sigmax; sh.sigflag[0] |= SH_SIGFAULT; - while(--sig>0) + for(sig=sh.sigmax; sig>0; sig--) { flag = sh.sigflag[sig]; if((flag&(SH_SIGDONE|SH_SIGIGNORE|SH_SIGINTERACTIVE)) && !(flag&(SH_SIGFAULT|SH_SIGOFF))) @@ -321,7 +325,8 @@ void sh_sigreset(register int mode) } else if(sig && mode>1) { - signal(sig,SIG_IGN); + if(sig!=SIGCHLD) + signal(sig,SIG_IGN); flag &= ~SH_SIGFAULT; flag |= SH_SIGOFF; } @@ -396,13 +401,25 @@ void sh_chktrap(void) } if(sh.sigflag[SIGALRM]&SH_SIGALRM) sh_timetraps(); +#ifdef SHOPT_BGX + if((sh.sigflag[SIGCHLD]&SH_SIGTRAP) && sh.st.trapcom[SIGCHLD]) + job_chldtrap(&sh,sh.st.trapcom[SIGCHLD],1); + while(--sig>=0 && sig!=SIGCHLD) +#else while(--sig>=0) +#endif /* SHOPT_BGX */ { if(sh.sigflag[sig]&SH_SIGTRAP) { sh.sigflag[sig] &= ~SH_SIGTRAP; if(trap=sh.st.trapcom[sig]) - sh_trap(trap,0); + { + Sfio_t *fp; + if(sig==SIGPIPE && (fp=sfpool((Sfio_t*)0,sh.outpool,SF_WRITE)) && sferror(fp)) + sfclose(fp); + sh.oldexit = SH_EXITSIG|sig; + sh_trap(trap,0); + } } } } @@ -465,7 +482,7 @@ int sh_trap(const char *trap, int mode) if(was_verbose) sh_onstate(SH_VERBOSE); exitset(); - if(jmpval>SH_JMPTRAP) + if(jmpval>SH_JMPTRAP && (((struct checkpt*)shp->jmpbuffer)->prev || ((struct checkpt*)shp->jmpbuffer)->mode==SH_JMPSCRIPT)) siglongjmp(*shp->jmplist,jmpval); return(shp->exitval); } @@ -568,8 +585,8 @@ void sh_done(void *ptr, register int sig) register int savxit = shp->exitval; shp->trapnote = 0; indone=1; - if(sig==0) - sig = shp->lastsig; + if(sig) + savxit = SH_EXITSIG|sig; if(shp->userinit) (*shp->userinit)(shp, -1); if(t=shp->st.trapcom[0]) @@ -604,6 +621,8 @@ void sh_done(void *ptr, register int sig) sfsync((Sfio_t*)sfstdin); sfsync((Sfio_t*)shp->outpool); sfsync((Sfio_t*)sfstdout); + if(savxit&SH_EXITSIG) + sig = savxit&SH_EXITMASK; if(sig) { /* generate fault termination code */ |