Exemplo n.º 1
0
/* note: i MUST NOT be 0 */
void
unwind(int i)
{
	/*
	 * This is a kludge. We need to restore everything that was
	 * changed in the new environment, see cid 1005090337C7A669439
	 * and 10050903386452ACBF1, but fail to even save things most of
	 * the time. funcs.c:c_eval() changes FERREXIT temporarily to 0,
	 * which needs to be restored thus (related to Debian #696823).
	 * We did not save the shell flags, so we use a special or'd
	 * value here... this is mostly to clean up behind *other*
	 * callers of unwind(LERROR) here; exec.c has the regular case.
	 */
	if (Flag(FERREXIT) & 0x80) {
		/* GNU bash does not run this trapsig */
		trapsig(ksh_SIGERR);
		Flag(FERREXIT) &= ~0x80;
	}

	/* ordering for EXIT vs ERR is a bit odd (this is what AT&T ksh does) */
	if (i == LEXIT || ((i == LERROR || i == LINTR) &&
	    sigtraps[ksh_SIGEXIT].trap &&
	    (!Flag(FTALKING) || Flag(FERREXIT)))) {
		++trap_nested;
		runtrap(&sigtraps[ksh_SIGEXIT], trap_nested == 1);
		--trap_nested;
		i = LLEAVE;
	} else if (Flag(FERREXIT) == 1 && (i == LERROR || i == LINTR)) {
		++trap_nested;
		runtrap(&sigtraps[ksh_SIGERR], trap_nested == 1);
		--trap_nested;
		i = LLEAVE;
	}

	while (/* CONSTCOND */ 1) {
		switch (e->type) {
		case E_PARSE:
		case E_FUNC:
		case E_INCL:
		case E_LOOP:
		case E_ERRH:
			kshlongjmp(e->jbuf, i);
			/* NOTREACHED */
		case E_NONE:
			if (i == LINTR)
				e->flags |= EF_FAKE_SIGDIE;
			/* FALLTHROUGH */
		default:
			quitenv(NULL);
			/*
			 * quitenv() may have reclaimed the memory
			 * used by source which will end badly when
			 * we jump to a function that expects it to
			 * be valid
			 */
			source = NULL;
		}
	}
}
Exemplo n.º 2
0
/*
 * run any pending traps.  If intr is set, only run traps that
 * can interrupt commands.
 */
void
runtraps(int flag)
{
	int i;
	Trap *p;

	if (ksh_tmout_state == TMOUT_LEAVING) {
		ksh_tmout_state = TMOUT_EXECUTING;
		warningf(false, "timed out waiting for input");
		unwind(LEXIT);
	} else
		/* XXX: this means the alarm will have no effect if a trap
		 * is caught after the alarm() was started...not good.
		 */
		ksh_tmout_state = TMOUT_EXECUTING;
	if (!flag)
		trap = 0;
	if (flag & TF_DFL_INTR)
		intrsig = 0;
	if (flag & TF_FATAL)
		fatal_trap = 0;
	for (p = sigtraps, i = NSIG+1; --i >= 0; p++)
		if (p->set && (!flag ||
		    ((p->flags & flag) && p->trap == (char *) 0)))
			runtrap(p);
}