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:
Denis Vlasenko 2009-03-19 13:30:04 +00:00
parent 0354aba9a1
commit 4b875708c1

View File

@ -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;