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>
This commit is contained in:
parent
af3fd14e4d
commit
91836baf85
44
shell/hush.c
44
shell/hush.c
@ -5180,6 +5180,47 @@ static FILE *generate_stream_from_string(const char *s)
|
|||||||
xmove_fd(channel[1], 1);
|
xmove_fd(channel[1], 1);
|
||||||
/* Prevent it from trying to handle ctrl-z etc */
|
/* Prevent it from trying to handle ctrl-z etc */
|
||||||
IF_HUSH_JOB(G.run_list_level = 1;)
|
IF_HUSH_JOB(G.run_list_level = 1;)
|
||||||
|
/* Awful hack for `trap` or $(trap).
|
||||||
|
*
|
||||||
|
* http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
|
||||||
|
* contains an example where "trap" is executed in a subshell:
|
||||||
|
*
|
||||||
|
* save_traps=$(trap)
|
||||||
|
* ...
|
||||||
|
* eval "$save_traps"
|
||||||
|
*
|
||||||
|
* Standard does not say that "trap" in subshell shall print
|
||||||
|
* parent shell's traps. It only says that its output
|
||||||
|
* must have suitable form, but then, in the above example
|
||||||
|
* (which is not supposed to be normative), it implies that.
|
||||||
|
*
|
||||||
|
* bash (and probably other shell) does implement it
|
||||||
|
* (traps are reset to defaults, but "trap" still shows them),
|
||||||
|
* but as a result, "trap" logic is hopelessly messed up:
|
||||||
|
*
|
||||||
|
* # trap
|
||||||
|
* trap -- 'echo Ho' SIGWINCH <--- we have a handler
|
||||||
|
* # (trap) <--- trap is in subshell - no output (correct, traps are reset)
|
||||||
|
* # true | trap <--- trap is in subshell - no output (ditto)
|
||||||
|
* # echo `true | trap` <--- in subshell - output (but traps are reset!)
|
||||||
|
* trap -- 'echo Ho' SIGWINCH
|
||||||
|
* # echo `(trap)` <--- in subshell in subshell - output
|
||||||
|
* trap -- 'echo Ho' SIGWINCH
|
||||||
|
* # echo `true | (trap)` <--- in subshell in subshell in subshell - output!
|
||||||
|
* trap -- 'echo Ho' SIGWINCH
|
||||||
|
*
|
||||||
|
* The rules when to forget and when to not forget traps
|
||||||
|
* get really complex and nonsensical.
|
||||||
|
*
|
||||||
|
* Our solution: ONLY bare $(trap) or `trap` is special.
|
||||||
|
*/
|
||||||
|
s = skip_whitespace(s);
|
||||||
|
if (strncmp(s, "trap", 4) == 0 && (*skip_whitespace(s + 4) == '\0'))
|
||||||
|
{
|
||||||
|
static const char *const argv[] = { NULL, NULL };
|
||||||
|
builtin_trap((char**)argv);
|
||||||
|
exit(0); /* not _exit() - we need to fflush */
|
||||||
|
}
|
||||||
#if BB_MMU
|
#if BB_MMU
|
||||||
reset_traps_to_defaults();
|
reset_traps_to_defaults();
|
||||||
parse_and_run_string(s);
|
parse_and_run_string(s);
|
||||||
@ -7057,7 +7098,8 @@ static int FAST_FUNC builtin_trap(char **argv)
|
|||||||
if (G.traps[i]) {
|
if (G.traps[i]) {
|
||||||
printf("trap -- ");
|
printf("trap -- ");
|
||||||
print_escaped(G.traps[i]);
|
print_escaped(G.traps[i]);
|
||||||
printf(" %s\n", get_signame(i));
|
/* bash compat: it says SIGxxx, not just xxx */
|
||||||
|
printf(" SIG%s\n", get_signame(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*fflush(stdout); - done after each builtin anyway */
|
/*fflush(stdout); - done after each builtin anyway */
|
||||||
|
3
shell/hush_test/hush-trap/savetrap.right
Normal file
3
shell/hush_test/hush-trap/savetrap.right
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
trap -- 'echo WINCH!' SIGWINCH
|
||||||
|
trap -- 'echo WINCH!' SIGWINCH
|
||||||
|
Done
|
6
shell/hush_test/hush-trap/savetrap.tests
Executable file
6
shell/hush_test/hush-trap/savetrap.tests
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
trap 'echo WINCH!' SIGWINCH
|
||||||
|
v=` trap `
|
||||||
|
echo $v
|
||||||
|
v=`trap`
|
||||||
|
echo $v
|
||||||
|
echo Done
|
Loading…
x
Reference in New Issue
Block a user