aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-09-23 01:46:19 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-09-23 01:46:19 +0200
commit91836baf85ce6980a33c6ce38730928a4edc3c5a (patch)
tree4bb9751804629463dc9f8e3ff8aac7abd28815df
parentaf3fd14e4df87d8af833d5e7b97d285b4d137d60 (diff)
downloadbusybox-w32-91836baf85ce6980a33c6ce38730928a4edc3c5a.tar.gz
busybox-w32-91836baf85ce6980a33c6ce38730928a4edc3c5a.tar.bz2
busybox-w32-91836baf85ce6980a33c6ce38730928a4edc3c5a.zip
hush: fix `trap`
function old new delta expand_variables 2217 2280 +63 static.argv - 8 +8 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/hush.c44
-rw-r--r--shell/hush_test/hush-trap/savetrap.right3
-rwxr-xr-xshell/hush_test/hush-trap/savetrap.tests6
3 files changed, 52 insertions, 1 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 6b176c388..eaf911458 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -5180,6 +5180,47 @@ static FILE *generate_stream_from_string(const char *s)
5180 xmove_fd(channel[1], 1); 5180 xmove_fd(channel[1], 1);
5181 /* Prevent it from trying to handle ctrl-z etc */ 5181 /* Prevent it from trying to handle ctrl-z etc */
5182 IF_HUSH_JOB(G.run_list_level = 1;) 5182 IF_HUSH_JOB(G.run_list_level = 1;)
5183 /* Awful hack for `trap` or $(trap).
5184 *
5185 * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
5186 * contains an example where "trap" is executed in a subshell:
5187 *
5188 * save_traps=$(trap)
5189 * ...
5190 * eval "$save_traps"
5191 *
5192 * Standard does not say that "trap" in subshell shall print
5193 * parent shell's traps. It only says that its output
5194 * must have suitable form, but then, in the above example
5195 * (which is not supposed to be normative), it implies that.
5196 *
5197 * bash (and probably other shell) does implement it
5198 * (traps are reset to defaults, but "trap" still shows them),
5199 * but as a result, "trap" logic is hopelessly messed up:
5200 *
5201 * # trap
5202 * trap -- 'echo Ho' SIGWINCH <--- we have a handler
5203 * # (trap) <--- trap is in subshell - no output (correct, traps are reset)
5204 * # true | trap <--- trap is in subshell - no output (ditto)
5205 * # echo `true | trap` <--- in subshell - output (but traps are reset!)
5206 * trap -- 'echo Ho' SIGWINCH
5207 * # echo `(trap)` <--- in subshell in subshell - output
5208 * trap -- 'echo Ho' SIGWINCH
5209 * # echo `true | (trap)` <--- in subshell in subshell in subshell - output!
5210 * trap -- 'echo Ho' SIGWINCH
5211 *
5212 * The rules when to forget and when to not forget traps
5213 * get really complex and nonsensical.
5214 *
5215 * Our solution: ONLY bare $(trap) or `trap` is special.
5216 */
5217 s = skip_whitespace(s);
5218 if (strncmp(s, "trap", 4) == 0 && (*skip_whitespace(s + 4) == '\0'))
5219 {
5220 static const char *const argv[] = { NULL, NULL };
5221 builtin_trap((char**)argv);
5222 exit(0); /* not _exit() - we need to fflush */
5223 }
5183#if BB_MMU 5224#if BB_MMU
5184 reset_traps_to_defaults(); 5225 reset_traps_to_defaults();
5185 parse_and_run_string(s); 5226 parse_and_run_string(s);
@@ -7057,7 +7098,8 @@ static int FAST_FUNC builtin_trap(char **argv)
7057 if (G.traps[i]) { 7098 if (G.traps[i]) {
7058 printf("trap -- "); 7099 printf("trap -- ");
7059 print_escaped(G.traps[i]); 7100 print_escaped(G.traps[i]);
7060 printf(" %s\n", get_signame(i)); 7101 /* bash compat: it says SIGxxx, not just xxx */
7102 printf(" SIG%s\n", get_signame(i));
7061 } 7103 }
7062 } 7104 }
7063 /*fflush(stdout); - done after each builtin anyway */ 7105 /*fflush(stdout); - done after each builtin anyway */
diff --git a/shell/hush_test/hush-trap/savetrap.right b/shell/hush_test/hush-trap/savetrap.right
new file mode 100644
index 000000000..2d33427aa
--- /dev/null
+++ b/shell/hush_test/hush-trap/savetrap.right
@@ -0,0 +1,3 @@
1trap -- 'echo WINCH!' SIGWINCH
2trap -- 'echo WINCH!' SIGWINCH
3Done
diff --git a/shell/hush_test/hush-trap/savetrap.tests b/shell/hush_test/hush-trap/savetrap.tests
new file mode 100755
index 000000000..6492e86a2
--- /dev/null
+++ b/shell/hush_test/hush-trap/savetrap.tests
@@ -0,0 +1,6 @@
1trap 'echo WINCH!' SIGWINCH
2v=` trap `
3echo $v
4v=`trap`
5echo $v
6echo Done