/* 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
#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 )
barrier(); \
curdir = nullstr; \
physdir = nullstr; \
+ trap_ptr = trap; \
} while (0)
#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;
*
* 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();
}
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++;