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>
This commit is contained in:
Denys Vlasenko 2009-09-25 00:06:51 +02:00
parent 0800e3af75
commit 21d87d495a
5 changed files with 38 additions and 9 deletions

View File

@ -193,6 +193,7 @@ struct globals_misc {
/* indicates specified signal received */
uint8_t gotsig[NSIG - 1]; /* offset by 1: "signal" 0 is meaningless */
char *trap[NSIG];
char **trap_ptr; /* used only by "trap hack" */
/* Rarely referenced stuff */
#if ENABLE_ASH_RANDOM_SUPPORT
@ -222,6 +223,7 @@ extern struct globals_misc *const ash_ptr_to_globals_misc;
#define sigmode (G_misc.sigmode )
#define gotsig (G_misc.gotsig )
#define trap (G_misc.trap )
#define trap_ptr (G_misc.trap_ptr )
#define random_galois_LFSR (G_misc.random_galois_LFSR)
#define random_LCG (G_misc.random_LCG )
#define backgndpid (G_misc.backgndpid )
@ -231,6 +233,7 @@ extern struct globals_misc *const ash_ptr_to_globals_misc;
barrier(); \
curdir = nullstr; \
physdir = nullstr; \
trap_ptr = trap; \
} while (0)
@ -4539,7 +4542,7 @@ static void closescript(void);
#if !JOBS
# define forkchild(jp, n, mode) forkchild(jp, mode)
#endif
static void
static NOINLINE void
forkchild(struct job *jp, union node *n, int mode)
{
int oldlvl;
@ -4596,8 +4599,10 @@ forkchild(struct job *jp, union node *n, int mode)
*
* Our solution: ONLY bare $(trap) or `trap` is special.
*/
free(trap[0]); /* Prevent EXIT trap from firing in `trap` */
trap[0] = NULL;
/* This is needed to prevent EXIT trap firing and such
* (trap_ptr will be freed in trapcmd()) */
trap_ptr = memcpy(xmalloc(sizeof(trap)), trap, sizeof(trap));
memset(trap, 0, sizeof(trap));
} else {
clear_traps();
}
@ -12260,15 +12265,23 @@ trapcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
ap = argptr;
if (!*ap) {
for (signo = 0; signo < NSIG; signo++) {
if (trap[signo] != NULL) {
char *tr = trap_ptr[signo];
if (tr) {
out1fmt("trap -- %s %s%s\n",
single_quote(trap[signo]),
single_quote(tr),
(signo == 0 ? "" : "SIG"),
get_signame(signo));
if (trap_ptr != trap)
free(tr);
}
}
if (trap_ptr != trap) {
free(trap_ptr);
trap_ptr = trap;
}
return 0;
}
action = NULL;
if (ap[1])
action = *ap++;

View File

@ -1,3 +1,8 @@
trap -- 'echo Exiting' EXIT
trap -- 'echo WINCH!' SIGWINCH
trap -- 'echo Exiting' EXIT
trap -- 'echo WINCH!' SIGWINCH
trap -- 'echo Exiting' EXIT
trap -- 'echo WINCH!' SIGWINCH
Done
Exiting

View File

@ -1,6 +1,9 @@
trap 'echo Exiting' EXIT
trap 'echo WINCH!' SIGWINCH
v=` trap `
echo $v
echo "$v"
v=$( trap )
echo "$v"
v=`trap`
echo $v
echo "$v"
echo Done

View File

@ -1,3 +1,8 @@
trap -- 'echo Exiting' EXIT
trap -- 'echo WINCH!' SIGWINCH
trap -- 'echo Exiting' EXIT
trap -- 'echo WINCH!' SIGWINCH
trap -- 'echo Exiting' EXIT
trap -- 'echo WINCH!' SIGWINCH
Done
Exiting

View File

@ -1,6 +1,9 @@
trap 'echo Exiting' EXIT
trap 'echo WINCH!' SIGWINCH
v=` trap `
echo $v
echo "$v"
v=$( trap )
echo "$v"
v=`trap`
echo $v
echo "$v"
echo Done