ash: in dotrap(), do not clear gotsig[] for SIGINT if there is no handler
for it, otherwise raise interrupt gets confused later. The rest are readability fixes. function old new delta evaltreenr 817 818 +1 evaltree 817 818 +1 evalstring 88 89 +1 cmdloop 420 419 -1 evalskip 4 1 -3 breakcmd 84 81 -3 ash_main 1382 1379 -3 evalloop 183 177 -6 evalfor 231 225 -6 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/6 up/down: 3/-22) Total: -19 bytes
This commit is contained in:
parent
0354aba9a1
commit
4b875708c1
126
shell/ash.c
126
shell/ash.c
@ -162,6 +162,9 @@ struct globals_misc {
|
|||||||
// /* do we generate EXSIG events */
|
// /* do we generate EXSIG events */
|
||||||
// int exsig; /* counter */
|
// int exsig; /* counter */
|
||||||
volatile int suppressint; /* counter */
|
volatile int suppressint; /* counter */
|
||||||
|
// TODO: rename
|
||||||
|
// pendingsig -> pending_sig
|
||||||
|
// intpending -> pending_int
|
||||||
volatile /*sig_atomic_t*/ smallint intpending; /* 1 = got SIGINT */
|
volatile /*sig_atomic_t*/ smallint intpending; /* 1 = got SIGINT */
|
||||||
/* last pending signal */
|
/* last pending signal */
|
||||||
volatile /*sig_atomic_t*/ smallint pendingsig;
|
volatile /*sig_atomic_t*/ smallint pendingsig;
|
||||||
@ -210,7 +213,7 @@ struct globals_misc {
|
|||||||
#define S_HARD_IGN 4 /* signal is ignored permenantly */
|
#define S_HARD_IGN 4 /* signal is ignored permenantly */
|
||||||
|
|
||||||
/* indicates specified signal received */
|
/* 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];
|
char *trap[NSIG];
|
||||||
|
|
||||||
/* Rarely referenced stuff */
|
/* 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
|
* 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
|
* 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 raise_exception(int) NORETURN;
|
||||||
static void
|
static void
|
||||||
@ -305,7 +308,7 @@ static void raise_interrupt(void) NORETURN;
|
|||||||
static void
|
static void
|
||||||
raise_interrupt(void)
|
raise_interrupt(void)
|
||||||
{
|
{
|
||||||
int i;
|
int ex_type;
|
||||||
|
|
||||||
intpending = 0;
|
intpending = 0;
|
||||||
/* Signal is not automatically unmasked after it is raised,
|
/* Signal is not automatically unmasked after it is raised,
|
||||||
@ -313,16 +316,16 @@ raise_interrupt(void)
|
|||||||
sigprocmask_allsigs(SIG_UNBLOCK);
|
sigprocmask_allsigs(SIG_UNBLOCK);
|
||||||
/* pendingsig = 0; - now done in onsig() */
|
/* pendingsig = 0; - now done in onsig() */
|
||||||
|
|
||||||
i = EXSIG;
|
ex_type = EXSIG;
|
||||||
if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
|
if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
|
||||||
if (!(rootshell && iflag)) {
|
if (!(rootshell && iflag)) {
|
||||||
/* Kill ourself with SIGINT */
|
/* Kill ourself with SIGINT */
|
||||||
signal(SIGINT, SIG_DFL);
|
signal(SIGINT, SIG_DFL);
|
||||||
raise(SIGINT);
|
raise(SIGINT);
|
||||||
}
|
}
|
||||||
i = EXINT;
|
ex_type = EXINT;
|
||||||
}
|
}
|
||||||
raise_exception(i);
|
raise_exception(ex_type);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,37 +369,6 @@ force_int_on(void)
|
|||||||
raise_interrupt(); \
|
raise_interrupt(); \
|
||||||
} while (0)
|
} 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 */
|
/* ============ Stdout/stderr output */
|
||||||
|
|
||||||
@ -3287,6 +3259,39 @@ static smallint doing_jobctl; //references:8
|
|||||||
static void setjobctl(int);
|
static void setjobctl(int);
|
||||||
#endif
|
#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
|
* Set the signal handler for the specified signal. The routine figures
|
||||||
* out what it should be set to.
|
* out what it should be set to.
|
||||||
@ -7914,49 +7919,56 @@ defun(char *name, union node *func)
|
|||||||
INT_ON;
|
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 SKIPBREAK (1 << 0)
|
||||||
#define SKIPCONT (1 << 1)
|
#define SKIPCONT (1 << 1)
|
||||||
#define SKIPFUNC (1 << 2)
|
#define SKIPFUNC (1 << 2)
|
||||||
#define SKIPFILE (1 << 3)
|
#define SKIPFILE (1 << 3)
|
||||||
#define SKIPEVAL (1 << 4)
|
#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 skipcount; /* number of levels to skip */
|
||||||
static int funcnest; /* depth of function calls */
|
static int funcnest; /* depth of function calls */
|
||||||
static int loopnest; /* current loop nesting level */
|
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);
|
static int evalstring(char *s, int mask);
|
||||||
|
|
||||||
/*
|
/* Called to execute a trap.
|
||||||
* Called to execute a trap. Perhaps we should avoid entering new trap
|
* Single callsite - at the end of evaltree().
|
||||||
* handlers while we are executing a trap handler.
|
* 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
|
static int
|
||||||
dotrap(void)
|
dotrap(void)
|
||||||
{
|
{
|
||||||
char *p;
|
uint8_t *g;
|
||||||
char *q;
|
int sig;
|
||||||
int i;
|
uint8_t savestatus;
|
||||||
int savestatus;
|
|
||||||
int skip;
|
|
||||||
|
|
||||||
savestatus = exitstatus;
|
savestatus = exitstatus;
|
||||||
pendingsig = 0;
|
pendingsig = 0;
|
||||||
xbarrier();
|
xbarrier();
|
||||||
|
|
||||||
for (i = 1, q = gotsig; i < NSIG; i++, q++) {
|
for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) {
|
||||||
if (!*q)
|
int want_exexit;
|
||||||
continue;
|
char *t;
|
||||||
*q = '\0';
|
|
||||||
|
|
||||||
p = trap[i];
|
if (*g == 0)
|
||||||
if (!p)
|
|
||||||
continue;
|
continue;
|
||||||
skip = evalstring(p, SKIPEVAL);
|
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;
|
||||||
|
*g = 0;
|
||||||
|
if (!t)
|
||||||
|
continue;
|
||||||
|
want_exexit = evalstring(t, SKIPEVAL);
|
||||||
exitstatus = savestatus;
|
exitstatus = savestatus;
|
||||||
if (skip)
|
if (want_exexit)
|
||||||
return skip;
|
return want_exexit;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user