diff options
author | Ron Yorston <rmy@pobox.com> | 2023-08-15 08:42:28 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-08-15 08:42:28 +0100 |
commit | 44349e33d7cf05225f8c39cee7fc2b89cfc72ce8 (patch) | |
tree | 98a1aad0b1b663084732c8f76cff193d033dd67d | |
parent | 41384b4829db50c7b7ba07c720d299ce098d320d (diff) | |
download | busybox-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.c | 32 |
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 */ |
5887 | static void closescript(void); | 5883 | static 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 | ||
16929 | static struct globals_misc * | 16928 | static struct globals_misc * |
16930 | globals_misc_copy(void) | 16929 | globals_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 |
17236 | static void | 17238 | static void |
17237 | forkshell_init(const char *idstr) | 17239 | forkshell_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; |