/* 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; } } }
/* * 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); }