#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);
}

