fault.c revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Copyright (c) 1982-2007 AT&T Knowledge Ventures *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* by AT&T Knowledge Ventures *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Fault handling routines
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define abortsig(sig) (sig==SIGABRT || sig==SIGBUS || sig==SIGILL || sig==SIGSEGV)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char indone;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This exception handler is called after vmalloc() unlocks the region
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int malloc_done(Vmalloc_t* vm, int type, Void_t* val, Vmdisc_t* dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Most signals caught or ignored by the shell come here
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *trap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct checkpt *pp = (struct checkpt*)sh.jmplist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* reset handler */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SIGWINCH */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* critical region, save and process later */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* handle ignored signals */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((flag&SH_SIGINTERACTIVE) && sh_isstate(SH_INTERACTIVE) && !sh_isstate(SH_FORKED) && ! sh.subshell)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for TERM signal between fork/exec */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sig==SIGABRT || (abortsig(sig) && (ptr = malloc(1))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* mark signal and continue */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* abort inside malloc, process when malloc returns */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* VMFL defined when using vmalloc() */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * propogate signal to foreground group
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SIGTSTP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize signal handling
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* find the largest signal number in the table */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((sig=tp->sh_number&((1<<SH_SIGBITS)-1))>n && sig<SH_TRAP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Turn on trap handler for signal <sig>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void (*fun)(int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!((flag=sh.sigflag[sig])&(SH_SIGFAULT|SH_SIGOFF)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* don't set signal if already set or off by parent */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set signal handler so sh_done is called for all caught signals
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(--sig>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((flag&(SH_SIGDONE|SH_SIGIGNORE|SH_SIGINTERACTIVE)) && !(flag&(SH_SIGFAULT|SH_SIGOFF)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Restore to default signals
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Free the trap strings if mode is non-zero
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If mode>1 then ignored traps cause signal to be ignored
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *trap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(sig-- > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * free up trap if set and restore signal handler if modified
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *trap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * check for traps
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *trap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* execute errexit trap first */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(--sig>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * parse and execute the given trap string, stream or tree depending on mode
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * mode==0 for string, mode==1 for stream, mode==2 for parse tree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * exit the current scope and jump to an earlier one based on pp->mode
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct checkpt *pp = (struct checkpt*)sh.jmplist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int sig=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* ^Z detected by the shell */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh.subshell && sh_isstate(SH_MONITOR) && !sh_isstate(SH_STOPOK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* Handles ^Z for shell builtins, subshells, and functs */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* wait for child to stop */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* return to prompt mode */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* child process, put to sleep */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* stop child job */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* child resumes */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SIGTSTP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* unlock output pool */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SIGPIPE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This is the exit routine for the shell
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* avoid recursive call for set -e */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_ACCT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_EMACS)||sh_isoption(SH_VI)||sh_isoption(SH_GMACS))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((sh_isoption(SH_INTERACTIVE) && sh.login_sh) || (!sh_isoption(SH_INTERACTIVE) && (sig==SIGHUP)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* JOBS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strmatch((char*)0,(char*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* generate fault termination code */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */