aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-19 13:30:04 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-19 13:30:04 +0000
commit4b875708c13ec810e8fbd5721a68442f36a9210d (patch)
tree9c711b170d49cbc949f06964dd9cad0b51ec27ea
parent0354aba9a14e3c28934af505688acbb62437d95e (diff)
downloadbusybox-w32-4b875708c13ec810e8fbd5721a68442f36a9210d.tar.gz
busybox-w32-4b875708c13ec810e8fbd5721a68442f36a9210d.tar.bz2
busybox-w32-4b875708c13ec810e8fbd5721a68442f36a9210d.zip
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
-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 {
162// /* do we generate EXSIG events */ 162// /* do we generate EXSIG events */
163// int exsig; /* counter */ 163// int exsig; /* counter */
164 volatile int suppressint; /* counter */ 164 volatile int suppressint; /* counter */
165// TODO: rename
166// pendingsig -> pending_sig
167// intpending -> pending_int
165 volatile /*sig_atomic_t*/ smallint intpending; /* 1 = got SIGINT */ 168 volatile /*sig_atomic_t*/ smallint intpending; /* 1 = got SIGINT */
166 /* last pending signal */ 169 /* last pending signal */
167 volatile /*sig_atomic_t*/ smallint pendingsig; 170 volatile /*sig_atomic_t*/ smallint pendingsig;
@@ -210,7 +213,7 @@ struct globals_misc {
210#define S_HARD_IGN 4 /* signal is ignored permenantly */ 213#define S_HARD_IGN 4 /* signal is ignored permenantly */
211 214
212 /* indicates specified signal received */ 215 /* indicates specified signal received */
213 char gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */ 216 uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
214 char *trap[NSIG]; 217 char *trap[NSIG];
215 218
216 /* Rarely referenced stuff */ 219 /* Rarely referenced stuff */
@@ -279,7 +282,7 @@ static int isdigit_str9(const char *str)
279/* 282/*
280 * Called to raise an exception. Since C doesn't include exceptions, we 283 * Called to raise an exception. Since C doesn't include exceptions, we
281 * just do a longjmp to the exception handler. The type of exception is 284 * just do a longjmp to the exception handler. The type of exception is
282 * stored in the global variable "exception". 285 * stored in the global variable "exception_type".
283 */ 286 */
284static void raise_exception(int) NORETURN; 287static void raise_exception(int) NORETURN;
285static void 288static void
@@ -305,7 +308,7 @@ static void raise_interrupt(void) NORETURN;
305static void 308static void
306raise_interrupt(void) 309raise_interrupt(void)
307{ 310{
308 int i; 311 int ex_type;
309 312
310 intpending = 0; 313 intpending = 0;
311 /* Signal is not automatically unmasked after it is raised, 314 /* Signal is not automatically unmasked after it is raised,
@@ -313,16 +316,16 @@ raise_interrupt(void)
313 sigprocmask_allsigs(SIG_UNBLOCK); 316 sigprocmask_allsigs(SIG_UNBLOCK);
314 /* pendingsig = 0; - now done in onsig() */ 317 /* pendingsig = 0; - now done in onsig() */
315 318
316 i = EXSIG; 319 ex_type = EXSIG;
317 if (gotsig[SIGINT - 1] && !trap[SIGINT]) { 320 if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
318 if (!(rootshell && iflag)) { 321 if (!(rootshell && iflag)) {
319 /* Kill ourself with SIGINT */ 322 /* Kill ourself with SIGINT */
320 signal(SIGINT, SIG_DFL); 323 signal(SIGINT, SIG_DFL);
321 raise(SIGINT); 324 raise(SIGINT);
322 } 325 }
323 i = EXINT; 326 ex_type = EXINT;
324 } 327 }
325 raise_exception(i); 328 raise_exception(ex_type);
326 /* NOTREACHED */ 329 /* NOTREACHED */
327} 330}
328 331
@@ -366,37 +369,6 @@ force_int_on(void)
366 raise_interrupt(); \ 369 raise_interrupt(); \
367} while (0) 370} while (0)
368 371
369/*
370 * Ignore a signal. Avoids unnecessary system calls.
371 */
372static void
373ignoresig(int signo)
374{
375 if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
376 signal(signo, SIG_IGN);
377 }
378 sigmode[signo - 1] = S_HARD_IGN;
379}
380
381/*
382 * Signal handler. Only one usage site - in setsignal()
383 */
384static void
385onsig(int signo)
386{
387 gotsig[signo - 1] = 1;
388
389 if (/* exsig || */ (signo == SIGINT && !trap[SIGINT])) {
390 if (!suppressint) {
391 pendingsig = 0;
392 raise_interrupt(); /* does not return */
393 }
394 intpending = 1;
395 } else {
396 pendingsig = signo;
397 }
398}
399
400 372
401/* ============ Stdout/stderr output */ 373/* ============ Stdout/stderr output */
402 374
@@ -3288,6 +3260,39 @@ static void setjobctl(int);
3288#endif 3260#endif
3289 3261
3290/* 3262/*
3263 * Ignore a signal.
3264 */
3265static void
3266ignoresig(int signo)
3267{
3268 /* Avoid unnecessary system calls. Is it already SIG_IGNed? */
3269 if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
3270 /* No, need to do it */
3271 signal(signo, SIG_IGN);
3272 }
3273 sigmode[signo - 1] = S_HARD_IGN;
3274}
3275
3276/*
3277 * Signal handler. Only one usage site - in setsignal()
3278 */
3279static void
3280onsig(int signo)
3281{
3282 gotsig[signo - 1] = 1;
3283
3284 if (/* exsig || */ (signo == SIGINT && !trap[SIGINT])) {
3285 if (!suppressint) {
3286 pendingsig = 0;
3287 raise_interrupt(); /* does not return */
3288 }
3289 intpending = 1;
3290 } else {
3291 pendingsig = signo;
3292 }
3293}
3294
3295/*
3291 * Set the signal handler for the specified signal. The routine figures 3296 * Set the signal handler for the specified signal. The routine figures
3292 * out what it should be set to. 3297 * out what it should be set to.
3293 */ 3298 */
@@ -7914,49 +7919,56 @@ defun(char *name, union node *func)
7914 INT_ON; 7919 INT_ON;
7915} 7920}
7916 7921
7917static int evalskip; /* set if we are skipping commands */ 7922/* Reasons for skipping commands (see comment on breakcmd routine) */
7918/* reasons for skipping commands (see comment on breakcmd routine) */
7919#define SKIPBREAK (1 << 0) 7923#define SKIPBREAK (1 << 0)
7920#define SKIPCONT (1 << 1) 7924#define SKIPCONT (1 << 1)
7921#define SKIPFUNC (1 << 2) 7925#define SKIPFUNC (1 << 2)
7922#define SKIPFILE (1 << 3) 7926#define SKIPFILE (1 << 3)
7923#define SKIPEVAL (1 << 4) 7927#define SKIPEVAL (1 << 4)
7928static smallint evalskip; /* set to SKIPxxx if we are skipping commands */
7924static int skipcount; /* number of levels to skip */ 7929static int skipcount; /* number of levels to skip */
7925static int funcnest; /* depth of function calls */ 7930static int funcnest; /* depth of function calls */
7926static int loopnest; /* current loop nesting level */ 7931static int loopnest; /* current loop nesting level */
7927 7932
7928/* forward decl way out to parsing code - dotrap needs it */ 7933/* Forward decl way out to parsing code - dotrap needs it */
7929static int evalstring(char *s, int mask); 7934static int evalstring(char *s, int mask);
7930 7935
7931/* 7936/* Called to execute a trap.
7932 * Called to execute a trap. Perhaps we should avoid entering new trap 7937 * Single callsite - at the end of evaltree().
7933 * handlers while we are executing a trap handler. 7938 * If we return non-zero, exaltree raises EXEXIT exception.
7939 *
7940 * Perhaps we should avoid entering new trap handlers
7941 * while we are executing a trap handler. [is it a TODO?]
7934 */ 7942 */
7935static int 7943static int
7936dotrap(void) 7944dotrap(void)
7937{ 7945{
7938 char *p; 7946 uint8_t *g;
7939 char *q; 7947 int sig;
7940 int i; 7948 uint8_t savestatus;
7941 int savestatus;
7942 int skip;
7943 7949
7944 savestatus = exitstatus; 7950 savestatus = exitstatus;
7945 pendingsig = 0; 7951 pendingsig = 0;
7946 xbarrier(); 7952 xbarrier();
7947 7953
7948 for (i = 1, q = gotsig; i < NSIG; i++, q++) { 7954 for (sig = 1, g = gotsig; sig < NSIG; sig++, g++) {
7949 if (!*q) 7955 int want_exexit;
7950 continue; 7956 char *t;
7951 *q = '\0';
7952 7957
7953 p = trap[i]; 7958 if (*g == 0)
7954 if (!p) 7959 continue;
7960 t = trap[sig];
7961 /* non-trapped SIGINT is handled separately by raise_interrupt,
7962 * don't upset it by resetting gotsig[SIGINT-1] */
7963 if (sig == SIGINT && !t)
7955 continue; 7964 continue;
7956 skip = evalstring(p, SKIPEVAL); 7965 *g = 0;
7966 if (!t)
7967 continue;
7968 want_exexit = evalstring(t, SKIPEVAL);
7957 exitstatus = savestatus; 7969 exitstatus = savestatus;
7958 if (skip) 7970 if (want_exexit)
7959 return skip; 7971 return want_exexit;
7960 } 7972 }
7961 7973
7962 return 0; 7974 return 0;