diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-19 13:30:04 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-19 13:30:04 +0000 |
commit | 4b875708c13ec810e8fbd5721a68442f36a9210d (patch) | |
tree | 9c711b170d49cbc949f06964dd9cad0b51ec27ea | |
parent | 0354aba9a14e3c28934af505688acbb62437d95e (diff) | |
download | busybox-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.c | 126 |
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 | */ |
284 | static void raise_exception(int) NORETURN; | 287 | static void raise_exception(int) NORETURN; |
285 | static void | 288 | static void |
@@ -305,7 +308,7 @@ static void raise_interrupt(void) NORETURN; | |||
305 | static void | 308 | static void |
306 | raise_interrupt(void) | 309 | raise_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 | */ | ||
372 | static void | ||
373 | ignoresig(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 | */ | ||
384 | static void | ||
385 | onsig(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 | */ | ||
3265 | static void | ||
3266 | ignoresig(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 | */ | ||
3279 | static void | ||
3280 | onsig(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 | ||
7917 | static 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) |
7928 | static smallint evalskip; /* set to SKIPxxx if we are skipping commands */ | ||
7924 | static int skipcount; /* number of levels to skip */ | 7929 | static int skipcount; /* number of levels to skip */ |
7925 | static int funcnest; /* depth of function calls */ | 7930 | static int funcnest; /* depth of function calls */ |
7926 | static int loopnest; /* current loop nesting level */ | 7931 | static 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 */ |
7929 | static int evalstring(char *s, int mask); | 7934 | static 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 | */ |
7935 | static int | 7943 | static int |
7936 | dotrap(void) | 7944 | dotrap(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; |