aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c126
1 files changed, 69 insertions, 57 deletions
diff --git a/shell/ash.c b/shell/ash.c
index f93d73735..9bb1d421e 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -162,6 +162,9 @@ struct globals_misc {
// /* do we generate EXSIG events */
// int exsig; /* counter */
volatile int suppressint; /* counter */
+// TODO: rename
+// pendingsig -> pending_sig
+// intpending -> pending_int
volatile /*sig_atomic_t*/ smallint intpending; /* 1 = got SIGINT */
/* last pending signal */
volatile /*sig_atomic_t*/ smallint pendingsig;
@@ -210,7 +213,7 @@ struct globals_misc {
#define S_HARD_IGN 4 /* signal is ignored permenantly */
/* indicates specified signal received */
- char gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
+ uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
char *trap[NSIG];
/* Rarely referenced stuff */
@@ -279,7 +282,7 @@ static int isdigit_str9(const char *str)
/*
* Called to raise an exception. Since C doesn't include exceptions, we
* just do a longjmp to the exception handler. The type of exception is
- * stored in the global variable "exception".
+ * stored in the global variable "exception_type".
*/
static void raise_exception(int) NORETURN;
static void
@@ -305,7 +308,7 @@ static void raise_interrupt(void) NORETURN;
static void
raise_interrupt(void)
{
- int i;
+ int ex_type;
intpending = 0;
/* Signal is not automatically unmasked after it is raised,
@@ -313,16 +316,16 @@ raise_interrupt(void)
sigprocmask_allsigs(SIG_UNBLOCK);
/* pendingsig = 0; - now done in onsig() */
- i = EXSIG;
+ ex_type = EXSIG;
if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
if (!(rootshell && iflag)) {
/* Kill ourself with SIGINT */
signal(SIGINT, SIG_DFL);
raise(SIGINT);
}
- i = EXINT;
+ ex_type = EXINT;
}
- raise_exception(i);
+ raise_exception(ex_type);
/* NOTREACHED */
}
@@ -366,37 +369,6 @@ force_int_on(void)
raise_interrupt(); \
} while (0)
-/*
- * Ignore a signal. Avoids unnecessary system calls.
- */
-static void
-ignoresig(int signo)
-{
- if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
- signal(signo, SIG_IGN);
- }
- sigmode[signo - 1] = S_HARD_IGN;
-}
-
-/*
- * Signal handler. Only one usage site - in setsignal()
- */
-static void
-onsig(int signo)
-{
- gotsig[signo - 1] = 1;
-
- if (/* exsig || */ (signo == SIGINT && !trap[SIGINT])) {
- if (!suppressint) {
- pendingsig = 0;
- raise_interrupt(); /* does not return */
- }
- intpending = 1;
- } else {
- pendingsig = signo;
- }
-}
-
/* ============ Stdout/stderr output */
@@ -3288,6 +3260,39 @@ static void setjobctl(int);
#endif
/*
+ * Ignore a signal.
+ */
+static void
+ignoresig(int signo)
+{
+ /* Avoid unnecessary system calls. Is it already SIG_IGNed? */
+ if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
+ /* No, need to do it */
+ signal(signo, SIG_IGN);
+ }
+ sigmode[signo - 1] = S_HARD_IGN;
+}
+
+/*
+ * Signal handler. Only one usage site - in setsignal()
+ */
+static void
+onsig(int signo)
+{
+ gotsig[signo - 1] = 1;
+
+ if (/* exsig || */ (signo == SIGINT && !trap[SIGINT])) {
+ if (!suppressint) {
+ pendingsig = 0;
+ raise_interrupt(); /* does not return */
+ }
+ intpending = 1;
+ } else {
+ pendingsig = signo;
+ }
+}
+
+/*
* Set the signal handler for the specified signal. The routine figures
* out what it should be set to.
*/
@@ -7914,49 +7919,56 @@ defun(char *name, union node *func)
INT_ON;
}
-static int evalskip; /* set if we are skipping commands */
-/* reasons for skipping commands (see comment on breakcmd routine) */
+/* Reasons for skipping commands (see comment on breakcmd routine) */
#define SKIPBREAK (1 << 0)
#define SKIPCONT (1 << 1)
#define SKIPFUNC (1 << 2)
#define SKIPFILE (1 << 3)
#define SKIPEVAL (1 << 4)
+static smallint evalskip; /* set to SKIPxxx if we are skipping commands */
static int skipcount; /* number of levels to skip */
static int funcnest; /* depth of function calls */
static int loopnest; /* current loop nesting level */
-/* forward decl way out to parsing code - dotrap needs it */
+/* Forward decl way out to parsing code - dotrap needs it */
static int evalstring(char *s, int mask);
-/*
- * Called to execute a trap. Perhaps we should avoid entering new trap
- * handlers while we are executing a trap handler.
+/* Called to execute a trap.
+ * Single callsite - at the end of evaltree().
+ * If we return non-zero, exaltree raises EXEXIT exception.
+ *
+ * Perhaps we should avoid entering new trap handlers
+ * while we are executing a trap handler. [is it a TODO?]
*/
static int
dotrap(void)
{
- char *p;
- char *q;
- int i;
- int savestatus;
- int skip;
+ uint8_t *g;
+ int sig;
+ uint8_t savestatus;
savestatus = exitstatus;
pendingsig = 0;
xbarrier();
- for (i = 1, q = gotsig; i < NSIG; i++, q++) {
- if (!*q)
- continue;
- *q = '\0';
+ for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) {
+ int want_exexit;
+ char *t;
- p = trap[i];
- if (!p)
+ if (*g == 0)
+ continue;
+ t = trap[sig];
+ /* non-trapped SIGINT is handled separately by raise_interrupt,
+ * don't upset it by resetting gotsig[SIGINT-1] */
+ if (sig == SIGINT && !t)
continue;
- skip = evalstring(p, SKIPEVAL);
+ *g = 0;
+ if (!t)
+ continue;
+ want_exexit = evalstring(t, SKIPEVAL);
exitstatus = savestatus;
- if (skip)
- return skip;
+ if (want_exexit)
+ return want_exexit;
}
return 0;