diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-09-25 00:06:51 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-09-25 00:06:51 +0200 |
| commit | 21d87d495a78f9207d643a5bf99061d4401370ef (patch) | |
| tree | 455c5f4d34aad1885b7b793230cef11c5c750339 /shell | |
| parent | 0800e3af75461c6322427dab53d3526066453b04 (diff) | |
| download | busybox-w32-21d87d495a78f9207d643a5bf99061d4401370ef.tar.gz busybox-w32-21d87d495a78f9207d643a5bf99061d4401370ef.tar.bz2 busybox-w32-21d87d495a78f9207d643a5bf99061d4401370ef.zip | |
ash: better handling of EXIT trap in `trap` hack
function old new delta
forkchild - 602 +602
trapcmd 255 347 +92
ash_main 1362 1375 +13
evalvar 1371 1373 +2
popstring 140 134 -6
forkshell 835 248 -587
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 3/2 up/down: 709/-593) Total: 116 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 23 | ||||
| -rw-r--r-- | shell/ash_test/ash-signals/savetrap.right | 5 | ||||
| -rwxr-xr-x | shell/ash_test/ash-signals/savetrap.tests | 7 | ||||
| -rw-r--r-- | shell/hush_test/hush-trap/savetrap.right | 5 | ||||
| -rwxr-xr-x | shell/hush_test/hush-trap/savetrap.tests | 7 |
5 files changed, 38 insertions, 9 deletions
diff --git a/shell/ash.c b/shell/ash.c index 47f968b54..b30dc7728 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -193,6 +193,7 @@ struct globals_misc { | |||
| 193 | /* indicates specified signal received */ | 193 | /* indicates specified signal received */ |
| 194 | uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */ | 194 | uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */ |
| 195 | char *trap[NSIG]; | 195 | char *trap[NSIG]; |
| 196 | char **trap_ptr; /* used only by "trap hack" */ | ||
| 196 | 197 | ||
| 197 | /* Rarely referenced stuff */ | 198 | /* Rarely referenced stuff */ |
| 198 | #if ENABLE_ASH_RANDOM_SUPPORT | 199 | #if ENABLE_ASH_RANDOM_SUPPORT |
| @@ -222,6 +223,7 @@ extern struct globals_misc *const ash_ptr_to_globals_misc; | |||
| 222 | #define sigmode (G_misc.sigmode ) | 223 | #define sigmode (G_misc.sigmode ) |
| 223 | #define gotsig (G_misc.gotsig ) | 224 | #define gotsig (G_misc.gotsig ) |
| 224 | #define trap (G_misc.trap ) | 225 | #define trap (G_misc.trap ) |
| 226 | #define trap_ptr (G_misc.trap_ptr ) | ||
| 225 | #define random_galois_LFSR (G_misc.random_galois_LFSR) | 227 | #define random_galois_LFSR (G_misc.random_galois_LFSR) |
| 226 | #define random_LCG (G_misc.random_LCG ) | 228 | #define random_LCG (G_misc.random_LCG ) |
| 227 | #define backgndpid (G_misc.backgndpid ) | 229 | #define backgndpid (G_misc.backgndpid ) |
| @@ -231,6 +233,7 @@ extern struct globals_misc *const ash_ptr_to_globals_misc; | |||
| 231 | barrier(); \ | 233 | barrier(); \ |
| 232 | curdir = nullstr; \ | 234 | curdir = nullstr; \ |
| 233 | physdir = nullstr; \ | 235 | physdir = nullstr; \ |
| 236 | trap_ptr = trap; \ | ||
| 234 | } while (0) | 237 | } while (0) |
| 235 | 238 | ||
| 236 | 239 | ||
| @@ -4539,7 +4542,7 @@ static void closescript(void); | |||
| 4539 | #if !JOBS | 4542 | #if !JOBS |
| 4540 | # define forkchild(jp, n, mode) forkchild(jp, mode) | 4543 | # define forkchild(jp, n, mode) forkchild(jp, mode) |
| 4541 | #endif | 4544 | #endif |
| 4542 | static void | 4545 | static NOINLINE void |
| 4543 | forkchild(struct job *jp, union node *n, int mode) | 4546 | forkchild(struct job *jp, union node *n, int mode) |
| 4544 | { | 4547 | { |
| 4545 | int oldlvl; | 4548 | int oldlvl; |
| @@ -4596,8 +4599,10 @@ forkchild(struct job *jp, union node *n, int mode) | |||
| 4596 | * | 4599 | * |
| 4597 | * Our solution: ONLY bare $(trap) or `trap` is special. | 4600 | * Our solution: ONLY bare $(trap) or `trap` is special. |
| 4598 | */ | 4601 | */ |
| 4599 | free(trap[0]); /* Prevent EXIT trap from firing in `trap` */ | 4602 | /* This is needed to prevent EXIT trap firing and such |
| 4600 | trap[0] = NULL; | 4603 | * (trap_ptr will be freed in trapcmd()) */ |
| 4604 | trap_ptr = memcpy(xmalloc(sizeof(trap)), trap, sizeof(trap)); | ||
| 4605 | memset(trap, 0, sizeof(trap)); | ||
| 4601 | } else { | 4606 | } else { |
| 4602 | clear_traps(); | 4607 | clear_traps(); |
| 4603 | } | 4608 | } |
| @@ -12260,15 +12265,23 @@ trapcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
| 12260 | ap = argptr; | 12265 | ap = argptr; |
| 12261 | if (!*ap) { | 12266 | if (!*ap) { |
| 12262 | for (signo = 0; signo < NSIG; signo++) { | 12267 | for (signo = 0; signo < NSIG; signo++) { |
| 12263 | if (trap[signo] != NULL) { | 12268 | char *tr = trap_ptr[signo]; |
| 12269 | if (tr) { | ||
| 12264 | out1fmt("trap -- %s %s%s\n", | 12270 | out1fmt("trap -- %s %s%s\n", |
| 12265 | single_quote(trap[signo]), | 12271 | single_quote(tr), |
| 12266 | (signo == 0 ? "" : "SIG"), | 12272 | (signo == 0 ? "" : "SIG"), |
| 12267 | get_signame(signo)); | 12273 | get_signame(signo)); |
| 12274 | if (trap_ptr != trap) | ||
| 12275 | free(tr); | ||
| 12268 | } | 12276 | } |
| 12269 | } | 12277 | } |
| 12278 | if (trap_ptr != trap) { | ||
| 12279 | free(trap_ptr); | ||
| 12280 | trap_ptr = trap; | ||
| 12281 | } | ||
| 12270 | return 0; | 12282 | return 0; |
| 12271 | } | 12283 | } |
| 12284 | |||
| 12272 | action = NULL; | 12285 | action = NULL; |
| 12273 | if (ap[1]) | 12286 | if (ap[1]) |
| 12274 | action = *ap++; | 12287 | action = *ap++; |
diff --git a/shell/ash_test/ash-signals/savetrap.right b/shell/ash_test/ash-signals/savetrap.right index 2d33427aa..9cfd7a56c 100644 --- a/shell/ash_test/ash-signals/savetrap.right +++ b/shell/ash_test/ash-signals/savetrap.right | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | trap -- 'echo Exiting' EXIT | ||
| 1 | trap -- 'echo WINCH!' SIGWINCH | 2 | trap -- 'echo WINCH!' SIGWINCH |
| 3 | trap -- 'echo Exiting' EXIT | ||
| 4 | trap -- 'echo WINCH!' SIGWINCH | ||
| 5 | trap -- 'echo Exiting' EXIT | ||
| 2 | trap -- 'echo WINCH!' SIGWINCH | 6 | trap -- 'echo WINCH!' SIGWINCH |
| 3 | Done | 7 | Done |
| 8 | Exiting | ||
diff --git a/shell/ash_test/ash-signals/savetrap.tests b/shell/ash_test/ash-signals/savetrap.tests index 6492e86a2..c2b312fb8 100755 --- a/shell/ash_test/ash-signals/savetrap.tests +++ b/shell/ash_test/ash-signals/savetrap.tests | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | trap 'echo Exiting' EXIT | ||
| 1 | trap 'echo WINCH!' SIGWINCH | 2 | trap 'echo WINCH!' SIGWINCH |
| 2 | v=` trap ` | 3 | v=` trap ` |
| 3 | echo $v | 4 | echo "$v" |
| 5 | v=$( trap ) | ||
| 6 | echo "$v" | ||
| 4 | v=`trap` | 7 | v=`trap` |
| 5 | echo $v | 8 | echo "$v" |
| 6 | echo Done | 9 | echo Done |
diff --git a/shell/hush_test/hush-trap/savetrap.right b/shell/hush_test/hush-trap/savetrap.right index 2d33427aa..9cfd7a56c 100644 --- a/shell/hush_test/hush-trap/savetrap.right +++ b/shell/hush_test/hush-trap/savetrap.right | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | trap -- 'echo Exiting' EXIT | ||
| 1 | trap -- 'echo WINCH!' SIGWINCH | 2 | trap -- 'echo WINCH!' SIGWINCH |
| 3 | trap -- 'echo Exiting' EXIT | ||
| 4 | trap -- 'echo WINCH!' SIGWINCH | ||
| 5 | trap -- 'echo Exiting' EXIT | ||
| 2 | trap -- 'echo WINCH!' SIGWINCH | 6 | trap -- 'echo WINCH!' SIGWINCH |
| 3 | Done | 7 | Done |
| 8 | Exiting | ||
diff --git a/shell/hush_test/hush-trap/savetrap.tests b/shell/hush_test/hush-trap/savetrap.tests index 6492e86a2..c2b312fb8 100755 --- a/shell/hush_test/hush-trap/savetrap.tests +++ b/shell/hush_test/hush-trap/savetrap.tests | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | trap 'echo Exiting' EXIT | ||
| 1 | trap 'echo WINCH!' SIGWINCH | 2 | trap 'echo WINCH!' SIGWINCH |
| 2 | v=` trap ` | 3 | v=` trap ` |
| 3 | echo $v | 4 | echo "$v" |
| 5 | v=$( trap ) | ||
| 6 | echo "$v" | ||
| 4 | v=`trap` | 7 | v=`trap` |
| 5 | echo $v | 8 | echo "$v" |
| 6 | echo Done | 9 | echo Done |
