aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-08-15 08:42:28 +0100
committerRon Yorston <rmy@pobox.com>2023-08-15 08:42:28 +0100
commit44349e33d7cf05225f8c39cee7fc2b89cfc72ce8 (patch)
tree98a1aad0b1b663084732c8f76cff193d033dd67d
parent41384b4829db50c7b7ba07c720d299ce098d320d (diff)
downloadbusybox-w32-44349e33d7cf05225f8c39cee7fc2b89cfc72ce8.tar.gz
busybox-w32-44349e33d7cf05225f8c39cee7fc2b89cfc72ce8.tar.bz2
busybox-w32-44349e33d7cf05225f8c39cee7fc2b89cfc72ce8.zip
ash: improved support for trap built-in
Make it possible to use the 'trap' built-in with command substitution, process substitution and in pipelines. Costs 200-256 bytes.
-rw-r--r--shell/ash.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/shell/ash.c b/shell/ash.c
index c60657b9b..5c4a3073a 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -696,9 +696,7 @@ struct globals_misc {
696#define NTRAP_ERR NSIG 696#define NTRAP_ERR NSIG
697#define NTRAP_LAST NSIG 697#define NTRAP_LAST NSIG
698 698
699#if !ENABLE_PLATFORM_MINGW32
700 char **trap_ptr; /* used only by "trap hack" */ 699 char **trap_ptr; /* used only by "trap hack" */
701#endif
702 700
703 /* Rarely referenced stuff */ 701 /* Rarely referenced stuff */
704#if ENABLE_ASH_RANDOM_SUPPORT 702#if ENABLE_ASH_RANDOM_SUPPORT
@@ -750,9 +748,7 @@ extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc;
750#if ENABLE_PLATFORM_MINGW32 748#if ENABLE_PLATFORM_MINGW32
751#undef got_sigchld 749#undef got_sigchld
752#undef pending_sig 750#undef pending_sig
753#undef trap_ptr
754#define pending_sig (0) 751#define pending_sig (0)
755#define trap_ptr trap
756#endif 752#endif
757 753
758#define INIT_G_misc() do { \ 754#define INIT_G_misc() do { \
@@ -760,7 +756,7 @@ extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc;
760 savestatus = -1; \ 756 savestatus = -1; \
761 curdir = nullstr; \ 757 curdir = nullstr; \
762 physdir = nullstr; \ 758 physdir = nullstr; \
763 IF_NOT_PLATFORM_MINGW32(trap_ptr = trap;) \ 759 trap_ptr = trap; \
764} while (0) 760} while (0)
765 761
766 762
@@ -5859,7 +5855,6 @@ commandtext(union node *n)
5859 * 5855 *
5860 * Called with interrupts off. 5856 * Called with interrupts off.
5861 */ 5857 */
5862#if !ENABLE_PLATFORM_MINGW32
5863/* 5858/*
5864 * Clear traps on a fork. 5859 * Clear traps on a fork.
5865 */ 5860 */
@@ -5883,6 +5878,7 @@ clear_traps(void)
5883 INT_ON; 5878 INT_ON;
5884} 5879}
5885 5880
5881#if !ENABLE_PLATFORM_MINGW32
5886/* Lives far away from here, needed for forkchild */ 5882/* Lives far away from here, needed for forkchild */
5887static void closescript(void); 5883static void closescript(void);
5888 5884
@@ -16917,6 +16913,8 @@ globals_misc_size(struct datasize ds)
16917 ds.funcstringsize += align_len(physdir); 16913 ds.funcstringsize += align_len(physdir);
16918 ds.funcstringsize += align_len(arg0); 16914 ds.funcstringsize += align_len(arg0);
16919 ds.funcstringsize += align_len(commandname); 16915 ds.funcstringsize += align_len(commandname);
16916 for (int i = 0; i < ARRAY_SIZE(trap); i++)
16917 ds.funcstringsize += align_len(trap[i]);
16920 return ds; 16918 return ds;
16921} 16919}
16922 16920
@@ -16926,6 +16924,7 @@ globals_misc_size(struct datasize ds)
16926#undef arg0 16924#undef arg0
16927#undef commandname 16925#undef commandname
16928#undef nullstr 16926#undef nullstr
16927#undef trap
16929static struct globals_misc * 16928static struct globals_misc *
16930globals_misc_copy(void) 16929globals_misc_copy(void)
16931{ 16930{
@@ -16948,6 +16947,10 @@ globals_misc_copy(void)
16948 SAVE_PTR(new->arg0, xasprintf("arg0 '%s'", p->arg0 ?: "NULL"), FREE); 16947 SAVE_PTR(new->arg0, xasprintf("arg0 '%s'", p->arg0 ?: "NULL"), FREE);
16949 SAVE_PTR(new->commandname, 16948 SAVE_PTR(new->commandname,
16950 xasprintf("commandname '%s'", p->commandname ?: "NULL"), FREE); 16949 xasprintf("commandname '%s'", p->commandname ?: "NULL"), FREE);
16950 for (int i = 0; i < ARRAY_SIZE(p->trap); i++) {
16951 new->trap[i] = nodeckstrdup(p->trap[i]);
16952 SAVE_PTR(new->trap[i], xasprintf("trap[%d]", i), FREE);
16953 }
16951 return new; 16954 return new;
16952} 16955}
16953 16956
@@ -17231,7 +17234,6 @@ forkshell_prepare(struct forkshell *fs)
17231 return new; 17234 return new;
17232} 17235}
17233 17236
17234#undef trap
17235#undef trap_ptr 17237#undef trap_ptr
17236static void 17238static void
17237forkshell_init(const char *idstr) 17239forkshell_init(const char *idstr)
@@ -17280,8 +17282,7 @@ forkshell_init(const char *idstr)
17280 e = e->next; 17282 e = e->next;
17281 } 17283 }
17282 } 17284 }
17283 memset(fs->gmp->trap, 0, sizeof(fs->gmp->trap[0])*NSIG); 17285 fs->gmp->trap_ptr = fs->gmp->trap;
17284 /* fs->gmp->trap_ptr = fs->gmp->trap; */
17285 17286
17286 /* Set global variables */ 17287 /* Set global variables */
17287 gvpp = (struct globals_var **)&ash_ptr_to_globals_var; 17288 gvpp = (struct globals_var **)&ash_ptr_to_globals_var;
@@ -17328,6 +17329,19 @@ forkshell_init(const char *idstr)
17328 else { 17329 else {
17329 SetConsoleCtrlHandler(ctrl_handler, TRUE); 17330 SetConsoleCtrlHandler(ctrl_handler, TRUE);
17330 } 17331 }
17332
17333 if (fs->n && fs->n->type == NCMD /* is it single cmd? */
17334 /* && n->ncmd.args->type == NARG - always true? */
17335 && fs->n->ncmd.args && strcmp(fs->n->ncmd.args->narg.text, "trap") == 0
17336 && fs->n->ncmd.args->narg.next == NULL /* "trap" with no arguments */
17337 /* && n->ncmd.args->narg.backquote == NULL - do we need to check this? */
17338 ) {
17339 TRACE(("Trap hack\n"));
17340 /* Save trap handler strings for trap builtin to print */
17341 fs->gmp->trap_ptr = xmemdup(fs->gmp->trap, sizeof(fs->gmp->trap));
17342 /* Fall through into clearing traps */
17343 }
17344 clear_traps();
17331#if JOBS_WIN32 17345#if JOBS_WIN32
17332 /* do job control only in root shell */ 17346 /* do job control only in root shell */
17333 doing_jobctl = 0; 17347 doing_jobctl = 0;