da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Fault handling routines
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <fcin.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "io.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "history.h"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include "shlex.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "variables.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "jobs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "path.h"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include "builtins.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define abortsig(sig) (sig==SIGABRT || sig==SIGBUS || sig==SIGILL || sig==SIGSEGV)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char indone;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !_std_malloc
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include <vmalloc.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(VMFL) && (VMALLOC_VERSION>=20031205L)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This exception handler is called after vmalloc() unlocks the region
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int malloc_done(Vmalloc_t* vm, int type, Void_t* val, Vmdisc_t* dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->exceptf = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exit(SH_EXITSIG);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Most signals caught or ignored by the shell come here
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_fault(register int sig)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shell_t *shp = sh_getinterp();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int flag=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register char *trap;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register struct checkpt *pp = (struct checkpt*)shp->jmplist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int action=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* reset handler */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(sig&SH_TRAP))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(sig, sh_fault);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sig &= ~SH_TRAP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SIGWINCH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sig==SIGWINCH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int rows=0, cols=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int32_t v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin astwinsize(2,&rows,&cols);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(v = cols)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(COLUMNS, (char*)&v, NV_INT32|NV_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(v = rows)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(LINES, (char*)&v, NV_INT32|NV_RDONLY);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->winch++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SIGWINCH */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->savesig)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* critical region, save and process later */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->savesig = sig;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin trap = shp->st.trapcom[sig];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sig==SIGALRM && shp->bltinfun==b_sleep)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(trap && *trap)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->trapnote |= SH_SIGTRAP;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sigflag[sig] |= SH_SIGTRAP;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(shp->subshell && sig!=SIGINT && sig!=SIGQUIT && sig!=SIGWINCH && sig!=SIGCONT)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = SH_EXITSIG|sig;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_subfork();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* handle ignored signals */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(trap && *trap==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flag = shp->sigflag[sig]&~SH_SIGOFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!trap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sig==SIGINT && (shp->trapnote&SH_SIGIGNORE))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag&SH_SIGIGNORE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag&SH_SIGDONE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void *ptr=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((flag&SH_SIGINTERACTIVE) && sh_isstate(SH_INTERACTIVE) && !sh_isstate(SH_FORKED) && ! shp->subshell)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for TERM signal between fork/exec */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sig==SIGTERM && job.in_critical)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->trapnote |= SH_SIGTERM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lastsig = sig;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sigrelease(sig);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->mode < SH_JMPFUN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->mode = SH_JMPFUN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->mode = SH_JMPEXIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sig==SIGABRT || (abortsig(sig) && (ptr = malloc(1))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ptr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(ptr);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->subshell)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_done(shp,sig);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exit(SH_EXITSIG);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* mark signal and continue */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->trapnote |= SH_SIGSET;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sig <= shp->sigmax)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sigflag[sig] |= SH_SIGSET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(VMFL) && (VMALLOC_VERSION>=20031205L)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(abortsig(sig))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* abort inside malloc, process when malloc returns */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* VMFL defined when using vmalloc() */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Vmdisc_t* dp = vmdisc(Vmregion,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->exceptf = malloc_done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->mode==SH_JMPCMD)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lastsig = sig;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * propogate signal to foreground group
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sig==SIGHUP && job.curpgid)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin killpg(job.curpgid,SIGHUP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = SH_SIGTRAP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lastsig = sig;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = SH_SIGSET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SIGTSTP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sig==SIGTSTP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->trapnote |= SH_SIGTSTP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->mode==SH_JMPCMD && sh_isstate(SH_STOPOK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sigrelease(sig);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exit(SH_EXITSIG);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SIGTSTP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef ERROR_NOTIFY
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((error_info.flags&ERROR_NOTIFY) && shp->bltinfun)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin action = (*shp->bltinfun)(-sig,(char**)0,(void*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(action>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->bltinfun && shp->bltindata.notify)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->bltindata.sigset = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->trapnote |= flag;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sig <= shp->sigmax)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sigflag[sig] |= flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->mode==SH_JMPCMD && sh_isstate(SH_STOPOK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(action<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sigrelease(sig);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exit(SH_EXITSIG);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * initialize signal handling
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_siginit(void *ptr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = (Shell_t*)ptr;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register int sig, n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const struct shtable2 *tp = shtab_signals;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sig_begin();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* find the largest signal number in the table */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if defined(SIGRTMIN) && defined(SIGRTMAX)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((n = SIGRTMIN) > 0 && (sig = SIGRTMAX) > n && sig < SH_TRAP)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->sigruntime[SH_SIGRTMIN] = n;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->sigruntime[SH_SIGRTMAX] = sig;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif /* SIGRTMIN && SIGRTMAX */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz n = SIGTERM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*tp->sh_name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sig = (tp->sh_number&((1<<SH_SIGBITS)-1));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(sig-- & SH_TRAP))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((tp->sh_number>>SH_SIGBITS) & SH_SIGRUNTIME)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sig = shp->sigruntime[sig];
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sig>n && sig<SH_TRAP)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz n = sig;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sigmax = n++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.trapcom = (char**)calloc(n,sizeof(char*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sigflag = (unsigned char*)calloc(n,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sigmsg = (char**)calloc(n,sizeof(char*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(tp=shtab_signals; sig=tp->sh_number; tp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = (sig>>SH_SIGBITS);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((sig &= ((1<<SH_SIGBITS)-1)) > (shp->sigmax+1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sig--;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(n&SH_SIGRUNTIME)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sig = shp->sigruntime[sig];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sig>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sigflag[sig] = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*tp->sh_name)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sigmsg[sig] = (char*)tp->sh_value;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Turn on trap handler for signal <sig>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_sigtrap(register int sig)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void (*fun)(int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.st.otrapcom = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sig==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigdone();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!((flag=sh.sigflag[sig])&(SH_SIGFAULT|SH_SIGOFF)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* don't set signal if already set or off by parent */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fun=signal(sig,sh_fault))==SIG_IGN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(sig,SIG_IGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag |= SH_SIGOFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag |= SH_SIGFAULT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sig==SIGALRM && fun!=SIG_DFL && fun!=sh_fault)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(sig,fun);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag &= ~(SH_SIGSET|SH_SIGTRAP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.sigflag[sig] = flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set signal handler so sh_done is called for all caught signals
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_sigdone(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag, sig = sh.sigmax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.sigflag[0] |= SH_SIGFAULT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for(sig=sh.sigmax; sig>0; sig--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = sh.sigflag[sig];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((flag&(SH_SIGDONE|SH_SIGIGNORE|SH_SIGINTERACTIVE)) && !(flag&(SH_SIGFAULT|SH_SIGOFF)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_sigtrap(sig);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_sigreset(register int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *trap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag, sig=sh.st.trapmax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(sig-- > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trap=sh.st.trapcom[sig])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = sh.sigflag[sig]&~(SH_SIGTRAP|SH_SIGSET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*trap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(trap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.st.trapcom[sig] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(sig && mode>1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sig!=SIGCHLD)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz signal(sig,SIG_IGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag &= ~SH_SIGFAULT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag |= SH_SIGOFF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.sigflag[sig] = flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(sig=SH_DEBUGTRAP-1;sig>=0;sig--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trap=sh.st.trap[sig])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(trap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.st.trap[sig] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.st.trapcom[0] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.st.trapmax = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.trapnote=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * free up trap if set and restore signal handler if modified
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_sigclear(register int sig)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag = sh.sigflag[sig];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *trap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.st.otrapcom=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(flag&SH_SIGFAULT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag &= ~(SH_SIGTRAP|SH_SIGSET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trap=sh.st.trapcom[sig])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(!sh.subshell)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner free(trap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.st.trapcom[sig]=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.sigflag[sig] = flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * check for traps
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_chktrap(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int sig=sh.st.trapmax;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *trap;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(sh.trapnote&~SH_SIGIGNORE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sig=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.trapnote &= ~SH_SIGTRAP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* execute errexit trap first */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_ERREXIT) && sh.exitval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int sav_trapnote = sh.trapnote;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.trapnote &= ~SH_SIGSET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.st.trap[SH_ERRTRAP])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin trap = sh.st.trap[SH_ERRTRAP];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh.st.trap[SH_ERRTRAP] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_trap(trap,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh.st.trap[SH_ERRTRAP] = trap;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.trapnote = sav_trapnote;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_ERREXIT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt *pp = (struct checkpt*)sh.jmplist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->mode = SH_JMPEXIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exit(sh.exitval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.sigflag[SIGALRM]&SH_SIGALRM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_timetraps();
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#ifdef SHOPT_BGX
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((sh.sigflag[SIGCHLD]&SH_SIGTRAP) && sh.st.trapcom[SIGCHLD])
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz job_chldtrap(&sh,sh.st.trapcom[SIGCHLD],1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif /* SHOPT_BGX */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner while(--sig>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#ifdef SHOPT_BGX
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(sig==SIGCHLD)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner continue;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner#endif /* SHOPT_BGX */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.sigflag[sig]&SH_SIGTRAP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.sigflag[sig] &= ~SH_SIGTRAP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trap=sh.st.trapcom[sig])
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Sfio_t *fp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sig==SIGPIPE && (fp=sfpool((Sfio_t*)0,sh.outpool,SF_WRITE)) && sferror(fp))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfclose(fp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh.oldexit = SH_EXITSIG|sig;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_trap(trap,0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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 */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_trap(const char *trap, int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = sh_getinterp();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int jmpval, savxit = shp->exitval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int was_history = sh_isstate(SH_HISTORY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int was_verbose = sh_isstate(SH_VERBOSE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int staktop = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *savptr = stakfreeze(0);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner char ifstable[256];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Fcin_t savefc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsave(&savefc);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner memcpy(ifstable,shp->ifstable,sizeof(ifstable));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_HISTORY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_VERBOSE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->intrap++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,SH_JMPTRAP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exec((Shnode_t*)trap,sh_isstate(SH_ERREXIT));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (Sfio_t*)trap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = sfopen(NIL(Sfio_t*),trap,"s");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_eval(sp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(indone)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval==SH_JMPSCRIPT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin indone=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval==SH_JMPEXIT)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin savxit = shp->exitval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval=SH_JMPTRAP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->intrap--;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfsync(shp->outpool);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->indebug && jmpval!=SH_JMPEXIT && jmpval!=SH_JMPFUN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval=savxit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakset(savptr,staktop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcrestore(&savefc);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner memcpy(shp->ifstable,ifstable,sizeof(ifstable));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(was_history)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_HISTORY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(was_verbose)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_VERBOSE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exitset();
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(jmpval>SH_JMPTRAP && (((struct checkpt*)shp->jmpbuffer)->prev || ((struct checkpt*)shp->jmpbuffer)->mode==SH_JMPSCRIPT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin siglongjmp(*shp->jmplist,jmpval);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(shp->exitval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * exit the current scope and jump to an earlier one based on pp->mode
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_exit(register int xno)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register struct checkpt *pp = (struct checkpt*)shp->jmplist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int sig=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t* pool;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval=xno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(xno==SH_EXITSIG)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval |= (sig=shp->lastsig);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SIGTSTP
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->trapnote&SH_SIGTSTP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* ^Z detected by the shell */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->trapnote = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sigflag[SIGTSTP] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->subshell && sh_isstate(SH_MONITOR) && !sh_isstate(SH_STOPOK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_TIMING))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* Handles ^Z for shell builtins, subshells, and functs */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lastsig = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_MONITOR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_STOPOK);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->trapnote = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->subshell && (sig=sh_fork(0,NIL(int*))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.curpgid = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.parent = (pid_t)-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job_wait(sig);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.parent = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sigflag[SIGTSTP] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* wait for child to stop */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = (SH_EXITSIG|SIGTSTP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* return to prompt mode */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->mode = SH_JMPERREXIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->subshell)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_subfork();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* child process, put to sleep */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_STOPOK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_MONITOR);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sigflag[SIGTSTP] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* stop child job */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin killpg(job.curpgid,SIGTSTP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* child resumes */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job_clear();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->forked = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->exitval = (xno&SH_EXITMASK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SIGTSTP */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* unlock output pool */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_NOTRACK);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(pool=sfpool(NIL(Sfio_t*),shp->outpool,SF_WRITE)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin pool = shp->outpool; /* can't happen? */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclrlock(pool);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SIGPIPE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->lastsig==SIGPIPE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfpurge(pool);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SIGPIPE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclrlock(sfstdin);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!pp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_done(shp,sig);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->prefix = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->mktype = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp->mode == SH_JMPSCRIPT && !pp->prev)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_done(shp,sig);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(pp->mode)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin siglongjmp(pp->buff,pp->mode);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void array_notify(Namval_t *np, void *data)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namarr_t *ap = nv_arrayptr(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin NOT_USED(data);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(ap && ap->fun)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (*ap->fun)(np, 0, NV_AFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This is the exit routine for the shell
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_done(void *ptr, register int sig)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = (Shell_t*)ptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *t;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int savxit = shp->exitval;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->trapnote = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin indone=1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sig)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz savxit = SH_EXITSIG|sig;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->userinit)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (*shp->userinit)(shp, -1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(t=shp->st.trapcom[0])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.trapcom[0]=0; /*should free but not long */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->oldexit = savxit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_trap(t,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin savxit = shp->exitval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* avoid recursive call for set -e */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_ERREXIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_chktrap();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_scan(shp->var_tree,array_notify,(void*)0,NV_ARRAY,NV_ARRAY);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_freeup(shp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_ACCT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_accend();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_ACCT */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_VSH || SHOPT_ESH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_EMACS)||sh_isoption(SH_VI)||sh_isoption(SH_GMACS))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tty_cooked(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef JOBS
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((sh_isoption(SH_INTERACTIVE) && shp->login_sh) || (!sh_isoption(SH_INTERACTIVE) && (sig==SIGHUP)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job_walk(sfstderr,job_terminate,SIGHUP,NIL(char**));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* JOBS */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin job_close(shp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_search("VMTRACE", shp->var_tree,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strmatch((char*)0,(char*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync((Sfio_t*)sfstdin);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfsync((Sfio_t*)shp->outpool);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync((Sfio_t*)sfstdout);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(savxit&SH_EXITSIG)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sig = savxit&SH_EXITMASK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sig)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* generate fault termination code */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin signal(sig,SIG_DFL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sigrelease(sig);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin kill(getpid(),sig);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pause();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_NOEXEC))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin kiaclose((Lex_t*)shp->lex_context);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin exit(savxit&SH_EXITMASK);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin