#include "rc.h" int interrupted; Ref ntrap; /* runs in a different thread */ void dointr(void) { //fprint(2, "rcsh: intr (runq=%p)\n", runq); incref(&ntrap); } void dotrap(void) { Var *trapreq; Word *starval; //fprint(2, "dotrap (runq=%p)\n", runq); while(decref(&ntrap) >= 0) { if(flag['S']) exits(truestatus()?"":getstatus()); starval=vlook("*")->val; trapreq=vlook("sigint"); if(trapreq->fn){ start(trapreq->fn, trapreq->pc, (Var*)0); runq->local=newvar(strdup("*"), runq->local); runq->local->val=copywords(starval, (Word*)0); runq->local->changed=1; runq->redir=runq->startredir=0; } else { /* * run the stack down until we uncover the * command reading loop. Xreturn will exit * if there is none (i.e. if this is not * an interactive rc.) */ while(!runq->iflag){ print("ret from %s (q %p)\n", runq->cmdfile, runq); Xreturn(); } } } incref(&ntrap); } static char *sigfnname[]= { "sigexit", "sighup", "sigint", "sigquit", "sigalrm", "sigkill", "sigfpe", "sigterm", 0 }; static char *sigstr[]= { "exit", /* can't happen */ "hangup", "interrupt", "quit", /* can't happen */ "alarm", "kill", "sys: fp: ", "term", "child status", 0 }; void notifyf(void *arg, char *s) { int i; USED(arg); for(i=0;sigstr[i];i++) if(strncmp(s, sigstr[i], strlen(sigstr[i]))==0){ if(strncmp(s, "sys: ", 5)!=0) interrupted=1; goto Out; } pfmt(err, "rc: note: %s\n", s); noted(NDFLT); return; Out: if(strcmp(s, "interrupt")!=0) incref(&ntrap); if(ntrap.ref>=32){ /* rc is probably in a trap loop */ pfmt(err, "rc: Too many traps (trap %s), aborting\n", s); abort(); } noted(NCONT); }