aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/ash.c23
-rw-r--r--shell/ash_test/ash-signals/savetrap.right5
-rwxr-xr-xshell/ash_test/ash-signals/savetrap.tests7
-rw-r--r--shell/hush_test/hush-trap/savetrap.right5
-rwxr-xr-xshell/hush_test/hush-trap/savetrap.tests7
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
4542static void 4545static NOINLINE void
4543forkchild(struct job *jp, union node *n, int mode) 4546forkchild(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 @@
1trap -- 'echo Exiting' EXIT
1trap -- 'echo WINCH!' SIGWINCH 2trap -- 'echo WINCH!' SIGWINCH
3trap -- 'echo Exiting' EXIT
4trap -- 'echo WINCH!' SIGWINCH
5trap -- 'echo Exiting' EXIT
2trap -- 'echo WINCH!' SIGWINCH 6trap -- 'echo WINCH!' SIGWINCH
3Done 7Done
8Exiting
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 @@
1trap 'echo Exiting' EXIT
1trap 'echo WINCH!' SIGWINCH 2trap 'echo WINCH!' SIGWINCH
2v=` trap ` 3v=` trap `
3echo $v 4echo "$v"
5v=$( trap )
6echo "$v"
4v=`trap` 7v=`trap`
5echo $v 8echo "$v"
6echo Done 9echo 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 @@
1trap -- 'echo Exiting' EXIT
1trap -- 'echo WINCH!' SIGWINCH 2trap -- 'echo WINCH!' SIGWINCH
3trap -- 'echo Exiting' EXIT
4trap -- 'echo WINCH!' SIGWINCH
5trap -- 'echo Exiting' EXIT
2trap -- 'echo WINCH!' SIGWINCH 6trap -- 'echo WINCH!' SIGWINCH
3Done 7Done
8Exiting
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 @@
1trap 'echo Exiting' EXIT
1trap 'echo WINCH!' SIGWINCH 2trap 'echo WINCH!' SIGWINCH
2v=` trap ` 3v=` trap `
3echo $v 4echo "$v"
5v=$( trap )
6echo "$v"
4v=`trap` 7v=`trap`
5echo $v 8echo "$v"
6echo Done 9echo Done