hush: make read and trap builtins optional
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
1125d7d680
commit
7a85c60e7e
1 changed files with 118 additions and 71 deletions
189
shell/hush.c
189
shell/hush.c
|
@ -49,7 +49,6 @@
|
||||||
* [un]alias, command, fc, getopts, newgrp, readonly, times
|
* [un]alias, command, fc, getopts, newgrp, readonly, times
|
||||||
* make complex ${var%...} constructs support optional
|
* make complex ${var%...} constructs support optional
|
||||||
* make here documents optional
|
* make here documents optional
|
||||||
* make trap, read, ulimit builtins optional
|
|
||||||
*
|
*
|
||||||
* Bash compat TODO:
|
* Bash compat TODO:
|
||||||
* redirection of stdout+stderr: &> and >&
|
* redirection of stdout+stderr: &> and >&
|
||||||
|
@ -110,41 +109,6 @@
|
||||||
//config: help
|
//config: help
|
||||||
//config: Enable {abc,def} extension.
|
//config: Enable {abc,def} extension.
|
||||||
//config:
|
//config:
|
||||||
//config:config HUSH_HELP
|
|
||||||
//config: bool "help builtin"
|
|
||||||
//config: default y
|
|
||||||
//config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
|
|
||||||
//config: help
|
|
||||||
//config: Enable help builtin in hush. Code size + ~1 kbyte.
|
|
||||||
//config:
|
|
||||||
//config:config HUSH_PRINTF
|
|
||||||
//config: bool "printf builtin"
|
|
||||||
//config: default y
|
|
||||||
//config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
|
|
||||||
//config: help
|
|
||||||
//config: Enable printf builtin in hush.
|
|
||||||
//config:
|
|
||||||
//config:config HUSH_KILL
|
|
||||||
//config: bool "kill builtin (for kill %jobspec)"
|
|
||||||
//config: default y
|
|
||||||
//config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
|
|
||||||
//config: help
|
|
||||||
//config: Enable kill builtin in hush.
|
|
||||||
//config:
|
|
||||||
//config:config HUSH_WAIT
|
|
||||||
//config: bool "wait builtin"
|
|
||||||
//config: default y
|
|
||||||
//config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
|
|
||||||
//config: help
|
|
||||||
//config: Enable wait builtin in hush.
|
|
||||||
//config:
|
|
||||||
//config:config HUSH_TYPE
|
|
||||||
//config: bool "type builtin"
|
|
||||||
//config: default y
|
|
||||||
//config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
|
|
||||||
//config: help
|
|
||||||
//config: Enable type builtin in hush.
|
|
||||||
//config:
|
|
||||||
//config:config HUSH_INTERACTIVE
|
//config:config HUSH_INTERACTIVE
|
||||||
//config: bool "Interactive mode"
|
//config: bool "Interactive mode"
|
||||||
//config: default y
|
//config: default y
|
||||||
|
@ -209,7 +173,7 @@
|
||||||
//config: Enable support for shell functions in hush. +800 bytes.
|
//config: Enable support for shell functions in hush. +800 bytes.
|
||||||
//config:
|
//config:
|
||||||
//config:config HUSH_LOCAL
|
//config:config HUSH_LOCAL
|
||||||
//config: bool "Support local builtin"
|
//config: bool "local builtin"
|
||||||
//config: default y
|
//config: default y
|
||||||
//config: depends on HUSH_FUNCTIONS
|
//config: depends on HUSH_FUNCTIONS
|
||||||
//config: help
|
//config: help
|
||||||
|
@ -238,6 +202,62 @@
|
||||||
//config: This instructs hush to print commands before execution.
|
//config: This instructs hush to print commands before execution.
|
||||||
//config: Adds ~300 bytes.
|
//config: Adds ~300 bytes.
|
||||||
//config:
|
//config:
|
||||||
|
//config:config HUSH_HELP
|
||||||
|
//config: bool "help builtin"
|
||||||
|
//config: default y
|
||||||
|
//config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
|
||||||
|
//config: help
|
||||||
|
//config: Enable help builtin in hush. Code size + ~1 kbyte.
|
||||||
|
//config:
|
||||||
|
//config:config HUSH_PRINTF
|
||||||
|
//config: bool "printf builtin"
|
||||||
|
//config: default y
|
||||||
|
//config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
|
||||||
|
//config: help
|
||||||
|
//config: Enable printf builtin in hush.
|
||||||
|
//config:
|
||||||
|
//config:config HUSH_KILL
|
||||||
|
//config: bool "kill builtin (for kill %jobspec)"
|
||||||
|
//config: default y
|
||||||
|
//config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
|
||||||
|
//config: help
|
||||||
|
//config: Enable kill builtin in hush.
|
||||||
|
//config:
|
||||||
|
//config:config HUSH_WAIT
|
||||||
|
//config: bool "wait builtin"
|
||||||
|
//config: default y
|
||||||
|
//config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
|
||||||
|
//config: help
|
||||||
|
//config: Enable wait builtin in hush.
|
||||||
|
//config:
|
||||||
|
//config:config HUSH_TRAP
|
||||||
|
//config: bool "trap builtin"
|
||||||
|
//config: default y
|
||||||
|
//config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
|
||||||
|
//config: help
|
||||||
|
//config: Enable trap builtin in hush.
|
||||||
|
//config:
|
||||||
|
//config:config HUSH_ULIMIT
|
||||||
|
//config: bool "ulimit builtin"
|
||||||
|
//config: default y
|
||||||
|
//config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
|
||||||
|
//config: help
|
||||||
|
//config: Enable ulimit builtin in hush.
|
||||||
|
//config:
|
||||||
|
//config:config HUSH_TYPE
|
||||||
|
//config: bool "type builtin"
|
||||||
|
//config: default y
|
||||||
|
//config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
|
||||||
|
//config: help
|
||||||
|
//config: Enable type builtin in hush.
|
||||||
|
//config:
|
||||||
|
//config:config HUSH_READ
|
||||||
|
//config: bool "read builtin"
|
||||||
|
//config: default y
|
||||||
|
//config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH
|
||||||
|
//config: help
|
||||||
|
//config: Enable read builtin in hush.
|
||||||
|
//config:
|
||||||
//config:config MSH
|
//config:config MSH
|
||||||
//config: bool "msh (deprecated: aliased to hush)"
|
//config: bool "msh (deprecated: aliased to hush)"
|
||||||
//config: default n
|
//config: default n
|
||||||
|
@ -842,7 +862,12 @@ struct globals {
|
||||||
#else
|
#else
|
||||||
# define G_fatal_sig_mask 0
|
# define G_fatal_sig_mask 0
|
||||||
#endif
|
#endif
|
||||||
|
#if ENABLE_HUSH_TRAP
|
||||||
char **traps; /* char *traps[NSIG] */
|
char **traps; /* char *traps[NSIG] */
|
||||||
|
# define G_traps G.traps
|
||||||
|
#else
|
||||||
|
# define G_traps ((char**)NULL)
|
||||||
|
#endif
|
||||||
sigset_t pending_set;
|
sigset_t pending_set;
|
||||||
#if HUSH_DEBUG
|
#if HUSH_DEBUG
|
||||||
unsigned long memleak_value;
|
unsigned long memleak_value;
|
||||||
|
@ -892,12 +917,16 @@ static int builtin_memleak(char **argv) FAST_FUNC;
|
||||||
static int builtin_printf(char **argv) FAST_FUNC;
|
static int builtin_printf(char **argv) FAST_FUNC;
|
||||||
#endif
|
#endif
|
||||||
static int builtin_pwd(char **argv) FAST_FUNC;
|
static int builtin_pwd(char **argv) FAST_FUNC;
|
||||||
|
#if ENABLE_HUSH_READ
|
||||||
static int builtin_read(char **argv) FAST_FUNC;
|
static int builtin_read(char **argv) FAST_FUNC;
|
||||||
|
#endif
|
||||||
static int builtin_set(char **argv) FAST_FUNC;
|
static int builtin_set(char **argv) FAST_FUNC;
|
||||||
static int builtin_shift(char **argv) FAST_FUNC;
|
static int builtin_shift(char **argv) FAST_FUNC;
|
||||||
static int builtin_source(char **argv) FAST_FUNC;
|
static int builtin_source(char **argv) FAST_FUNC;
|
||||||
static int builtin_test(char **argv) FAST_FUNC;
|
static int builtin_test(char **argv) FAST_FUNC;
|
||||||
|
#if ENABLE_HUSH_TRAP
|
||||||
static int builtin_trap(char **argv) FAST_FUNC;
|
static int builtin_trap(char **argv) FAST_FUNC;
|
||||||
|
#endif
|
||||||
#if ENABLE_HUSH_TYPE
|
#if ENABLE_HUSH_TYPE
|
||||||
static int builtin_type(char **argv) FAST_FUNC;
|
static int builtin_type(char **argv) FAST_FUNC;
|
||||||
#endif
|
#endif
|
||||||
|
@ -973,7 +1002,9 @@ static const struct built_in_command bltins1[] = {
|
||||||
#if HUSH_DEBUG
|
#if HUSH_DEBUG
|
||||||
BLTIN("memleak" , builtin_memleak , NULL),
|
BLTIN("memleak" , builtin_memleak , NULL),
|
||||||
#endif
|
#endif
|
||||||
|
#if ENABLE_HUSH_READ
|
||||||
BLTIN("read" , builtin_read , "Input into variable"),
|
BLTIN("read" , builtin_read , "Input into variable"),
|
||||||
|
#endif
|
||||||
#if ENABLE_HUSH_FUNCTIONS
|
#if ENABLE_HUSH_FUNCTIONS
|
||||||
BLTIN("return" , builtin_return , "Return from a function"),
|
BLTIN("return" , builtin_return , "Return from a function"),
|
||||||
#endif
|
#endif
|
||||||
|
@ -982,12 +1013,16 @@ static const struct built_in_command bltins1[] = {
|
||||||
#if ENABLE_HUSH_BASH_COMPAT
|
#if ENABLE_HUSH_BASH_COMPAT
|
||||||
BLTIN("source" , builtin_source , "Run commands in a file"),
|
BLTIN("source" , builtin_source , "Run commands in a file"),
|
||||||
#endif
|
#endif
|
||||||
|
#if ENABLE_HUSH_TRAP
|
||||||
BLTIN("trap" , builtin_trap , "Trap signals"),
|
BLTIN("trap" , builtin_trap , "Trap signals"),
|
||||||
|
#endif
|
||||||
BLTIN("true" , builtin_true , NULL),
|
BLTIN("true" , builtin_true , NULL),
|
||||||
#if ENABLE_HUSH_TYPE
|
#if ENABLE_HUSH_TYPE
|
||||||
BLTIN("type" , builtin_type , "Show command type"),
|
BLTIN("type" , builtin_type , "Show command type"),
|
||||||
#endif
|
#endif
|
||||||
|
#if ENABLE_HUSH_ULIMIT
|
||||||
BLTIN("ulimit" , shell_builtin_ulimit , "Control resource limits"),
|
BLTIN("ulimit" , shell_builtin_ulimit , "Control resource limits"),
|
||||||
|
#endif
|
||||||
BLTIN("umask" , builtin_umask , "Set file creation mask"),
|
BLTIN("umask" , builtin_umask , "Set file creation mask"),
|
||||||
BLTIN("unset" , builtin_unset , "Unset variables"),
|
BLTIN("unset" , builtin_unset , "Unset variables"),
|
||||||
#if ENABLE_HUSH_WAIT
|
#if ENABLE_HUSH_WAIT
|
||||||
|
@ -1712,13 +1747,13 @@ static void hush_exit(int exitcode)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fflush_all();
|
fflush_all();
|
||||||
if (G.exiting <= 0 && G.traps && G.traps[0] && G.traps[0][0]) {
|
if (G.exiting <= 0 && G_traps && G_traps[0] && G_traps[0][0]) {
|
||||||
char *argv[3];
|
char *argv[3];
|
||||||
/* argv[0] is unused */
|
/* argv[0] is unused */
|
||||||
argv[1] = G.traps[0];
|
argv[1] = G_traps[0];
|
||||||
argv[2] = NULL;
|
argv[2] = NULL;
|
||||||
G.exiting = 1; /* prevent EXIT trap recursion */
|
G.exiting = 1; /* prevent EXIT trap recursion */
|
||||||
/* Note: G.traps[0] is not cleared!
|
/* Note: G_traps[0] is not cleared!
|
||||||
* "trap" will still show it, if executed
|
* "trap" will still show it, if executed
|
||||||
* in the handler */
|
* in the handler */
|
||||||
builtin_eval(argv);
|
builtin_eval(argv);
|
||||||
|
@ -1769,14 +1804,14 @@ static int check_and_run_traps(void)
|
||||||
} while (sig < NSIG);
|
} while (sig < NSIG);
|
||||||
break;
|
break;
|
||||||
got_sig:
|
got_sig:
|
||||||
if (G.traps && G.traps[sig]) {
|
if (G_traps && G_traps[sig]) {
|
||||||
debug_printf_exec("%s: sig:%d handler:'%s'\n", __func__, sig, G.traps[sig]);
|
debug_printf_exec("%s: sig:%d handler:'%s'\n", __func__, sig, G.traps[sig]);
|
||||||
if (G.traps[sig][0]) {
|
if (G_traps[sig][0]) {
|
||||||
/* We have user-defined handler */
|
/* We have user-defined handler */
|
||||||
smalluint save_rcode;
|
smalluint save_rcode;
|
||||||
char *argv[3];
|
char *argv[3];
|
||||||
/* argv[0] is unused */
|
/* argv[0] is unused */
|
||||||
argv[1] = G.traps[sig];
|
argv[1] = G_traps[sig];
|
||||||
argv[2] = NULL;
|
argv[2] = NULL;
|
||||||
save_rcode = G.last_exitcode;
|
save_rcode = G.last_exitcode;
|
||||||
builtin_eval(argv);
|
builtin_eval(argv);
|
||||||
|
@ -5924,13 +5959,15 @@ static void switch_off_special_sigs(unsigned mask)
|
||||||
sig++;
|
sig++;
|
||||||
if (!(mask & 1))
|
if (!(mask & 1))
|
||||||
continue;
|
continue;
|
||||||
if (G.traps) {
|
#if ENABLE_HUSH_TRAP
|
||||||
if (G.traps[sig] && !G.traps[sig][0])
|
if (G_traps) {
|
||||||
|
if (G_traps[sig] && !G_traps[sig][0])
|
||||||
/* trap is '', has to remain SIG_IGN */
|
/* trap is '', has to remain SIG_IGN */
|
||||||
continue;
|
continue;
|
||||||
free(G.traps[sig]);
|
free(G_traps[sig]);
|
||||||
G.traps[sig] = NULL;
|
G_traps[sig] = NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* We are here only if no trap or trap was not '' */
|
/* We are here only if no trap or trap was not '' */
|
||||||
install_sighandler(sig, SIG_DFL);
|
install_sighandler(sig, SIG_DFL);
|
||||||
}
|
}
|
||||||
|
@ -5947,7 +5984,7 @@ static void reset_traps_to_defaults(void)
|
||||||
/* This function is always called in a child shell
|
/* This function is always called in a child shell
|
||||||
* after fork (not vfork, NOMMU doesn't use this function).
|
* after fork (not vfork, NOMMU doesn't use this function).
|
||||||
*/
|
*/
|
||||||
unsigned sig;
|
IF_HUSH_TRAP(unsigned sig;)
|
||||||
unsigned mask;
|
unsigned mask;
|
||||||
|
|
||||||
/* Child shells are not interactive.
|
/* Child shells are not interactive.
|
||||||
|
@ -5956,35 +5993,37 @@ static void reset_traps_to_defaults(void)
|
||||||
* Same goes for SIGTERM, SIGHUP, SIGINT.
|
* Same goes for SIGTERM, SIGHUP, SIGINT.
|
||||||
*/
|
*/
|
||||||
mask = (G.special_sig_mask & SPECIAL_INTERACTIVE_SIGS) | G_fatal_sig_mask;
|
mask = (G.special_sig_mask & SPECIAL_INTERACTIVE_SIGS) | G_fatal_sig_mask;
|
||||||
if (!G.traps && !mask)
|
if (!G_traps && !mask)
|
||||||
return; /* already no traps and no special sigs */
|
return; /* already no traps and no special sigs */
|
||||||
|
|
||||||
/* Switch off special sigs */
|
/* Switch off special sigs */
|
||||||
switch_off_special_sigs(mask);
|
switch_off_special_sigs(mask);
|
||||||
#if ENABLE_HUSH_JOB
|
# if ENABLE_HUSH_JOB
|
||||||
G_fatal_sig_mask = 0;
|
G_fatal_sig_mask = 0;
|
||||||
#endif
|
# endif
|
||||||
G.special_sig_mask &= ~SPECIAL_INTERACTIVE_SIGS;
|
G.special_sig_mask &= ~SPECIAL_INTERACTIVE_SIGS;
|
||||||
/* SIGQUIT,SIGCHLD and maybe SPECIAL_JOBSTOP_SIGS
|
/* SIGQUIT,SIGCHLD and maybe SPECIAL_JOBSTOP_SIGS
|
||||||
* remain set in G.special_sig_mask */
|
* remain set in G.special_sig_mask */
|
||||||
|
|
||||||
if (!G.traps)
|
# if ENABLE_HUSH_TRAP
|
||||||
|
if (!G_traps)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Reset all sigs to default except ones with empty traps */
|
/* Reset all sigs to default except ones with empty traps */
|
||||||
for (sig = 0; sig < NSIG; sig++) {
|
for (sig = 0; sig < NSIG; sig++) {
|
||||||
if (!G.traps[sig])
|
if (!G_traps[sig])
|
||||||
continue; /* no trap: nothing to do */
|
continue; /* no trap: nothing to do */
|
||||||
if (!G.traps[sig][0])
|
if (!G_traps[sig][0])
|
||||||
continue; /* empty trap: has to remain SIG_IGN */
|
continue; /* empty trap: has to remain SIG_IGN */
|
||||||
/* sig has non-empty trap, reset it: */
|
/* sig has non-empty trap, reset it: */
|
||||||
free(G.traps[sig]);
|
free(G_traps[sig]);
|
||||||
G.traps[sig] = NULL;
|
G_traps[sig] = NULL;
|
||||||
/* There is no signal for trap 0 (EXIT) */
|
/* There is no signal for trap 0 (EXIT) */
|
||||||
if (sig == 0)
|
if (sig == 0)
|
||||||
continue;
|
continue;
|
||||||
install_sighandler(sig, pick_sighandler(sig));
|
install_sighandler(sig, pick_sighandler(sig));
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !BB_MMU */
|
#else /* !BB_MMU */
|
||||||
|
@ -6024,10 +6063,10 @@ static void re_execute_shell(char ***to_free, const char *s,
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
empty_trap_mask = 0;
|
empty_trap_mask = 0;
|
||||||
if (G.traps) {
|
if (G_traps) {
|
||||||
int sig;
|
int sig;
|
||||||
for (sig = 1; sig < NSIG; sig++) {
|
for (sig = 1; sig < NSIG; sig++) {
|
||||||
if (G.traps[sig] && !G.traps[sig][0])
|
if (G_traps[sig] && !G_traps[sig][0])
|
||||||
empty_trap_mask |= 1LL << sig;
|
empty_trap_mask |= 1LL << sig;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6220,6 +6259,7 @@ static FILE *generate_stream_from_string(const char *s, pid_t *pid_p)
|
||||||
xmove_fd(channel[1], 1);
|
xmove_fd(channel[1], 1);
|
||||||
/* Prevent it from trying to handle ctrl-z etc */
|
/* Prevent it from trying to handle ctrl-z etc */
|
||||||
IF_HUSH_JOB(G.run_list_level = 1;)
|
IF_HUSH_JOB(G.run_list_level = 1;)
|
||||||
|
# if ENABLE_HUSH_TRAP
|
||||||
/* Awful hack for `trap` or $(trap).
|
/* Awful hack for `trap` or $(trap).
|
||||||
*
|
*
|
||||||
* http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
|
* http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html
|
||||||
|
@ -6263,6 +6303,7 @@ static FILE *generate_stream_from_string(const char *s, pid_t *pid_p)
|
||||||
fflush_all(); /* important */
|
fflush_all(); /* important */
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
# if BB_MMU
|
# if BB_MMU
|
||||||
reset_traps_to_defaults();
|
reset_traps_to_defaults();
|
||||||
parse_and_run_string(s);
|
parse_and_run_string(s);
|
||||||
|
@ -8160,10 +8201,12 @@ static void install_sighandlers(unsigned mask)
|
||||||
if (old_handler == SIG_IGN) {
|
if (old_handler == SIG_IGN) {
|
||||||
/* oops... restore back to IGN, and record this fact */
|
/* oops... restore back to IGN, and record this fact */
|
||||||
install_sighandler(sig, old_handler);
|
install_sighandler(sig, old_handler);
|
||||||
if (!G.traps)
|
#if ENABLE_HUSH_TRAP
|
||||||
G.traps = xzalloc(sizeof(G.traps[0]) * NSIG);
|
if (!G_traps)
|
||||||
free(G.traps[sig]);
|
G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
|
||||||
G.traps[sig] = xzalloc(1); /* == xstrdup(""); */
|
free(G_traps[sig]);
|
||||||
|
G_traps[sig] = xzalloc(1); /* == xstrdup(""); */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8464,10 +8507,10 @@ int hush_main(int argc, char **argv)
|
||||||
if (empty_trap_mask != 0) {
|
if (empty_trap_mask != 0) {
|
||||||
int sig;
|
int sig;
|
||||||
install_special_sighandlers();
|
install_special_sighandlers();
|
||||||
G.traps = xzalloc(sizeof(G.traps[0]) * NSIG);
|
G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
|
||||||
for (sig = 1; sig < NSIG; sig++) {
|
for (sig = 1; sig < NSIG; sig++) {
|
||||||
if (empty_trap_mask & (1LL << sig)) {
|
if (empty_trap_mask & (1LL << sig)) {
|
||||||
G.traps[sig] = xzalloc(1); /* == xstrdup(""); */
|
G_traps[sig] = xzalloc(1); /* == xstrdup(""); */
|
||||||
install_sighandler(sig, SIG_IGN);
|
install_sighandler(sig, SIG_IGN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9114,6 +9157,7 @@ static int FAST_FUNC builtin_shift(char **argv)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_HUSH_READ
|
||||||
/* Interruptibility of read builtin in bash
|
/* Interruptibility of read builtin in bash
|
||||||
* (tested on bash-4.2.8 by sending signals (not by ^C)):
|
* (tested on bash-4.2.8 by sending signals (not by ^C)):
|
||||||
*
|
*
|
||||||
|
@ -9178,23 +9222,25 @@ static int FAST_FUNC builtin_read(char **argv)
|
||||||
|
|
||||||
return (uintptr_t)r;
|
return (uintptr_t)r;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_HUSH_TRAP
|
||||||
static int FAST_FUNC builtin_trap(char **argv)
|
static int FAST_FUNC builtin_trap(char **argv)
|
||||||
{
|
{
|
||||||
int sig;
|
int sig;
|
||||||
char *new_cmd;
|
char *new_cmd;
|
||||||
|
|
||||||
if (!G.traps)
|
if (!G_traps)
|
||||||
G.traps = xzalloc(sizeof(G.traps[0]) * NSIG);
|
G_traps = xzalloc(sizeof(G_traps[0]) * NSIG);
|
||||||
|
|
||||||
argv++;
|
argv++;
|
||||||
if (!*argv) {
|
if (!*argv) {
|
||||||
int i;
|
int i;
|
||||||
/* No args: print all trapped */
|
/* No args: print all trapped */
|
||||||
for (i = 0; i < NSIG; ++i) {
|
for (i = 0; i < NSIG; ++i) {
|
||||||
if (G.traps[i]) {
|
if (G_traps[i]) {
|
||||||
printf("trap -- ");
|
printf("trap -- ");
|
||||||
print_escaped(G.traps[i]);
|
print_escaped(G_traps[i]);
|
||||||
/* note: bash adds "SIG", but only if invoked
|
/* note: bash adds "SIG", but only if invoked
|
||||||
* as "bash". If called as "sh", or if set -o posix,
|
* as "bash". If called as "sh", or if set -o posix,
|
||||||
* then it prints short signal names.
|
* then it prints short signal names.
|
||||||
|
@ -9224,11 +9270,11 @@ static int FAST_FUNC builtin_trap(char **argv)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(G.traps[sig]);
|
free(G_traps[sig]);
|
||||||
G.traps[sig] = xstrdup(new_cmd);
|
G_traps[sig] = xstrdup(new_cmd);
|
||||||
|
|
||||||
debug_printf("trap: setting SIG%s (%i) to '%s'\n",
|
debug_printf("trap: setting SIG%s (%i) to '%s'\n",
|
||||||
get_signame(sig), sig, G.traps[sig]);
|
get_signame(sig), sig, G_traps[sig]);
|
||||||
|
|
||||||
/* There is no signal for 0 (EXIT) */
|
/* There is no signal for 0 (EXIT) */
|
||||||
if (sig == 0)
|
if (sig == 0)
|
||||||
|
@ -9268,6 +9314,7 @@ static int FAST_FUNC builtin_trap(char **argv)
|
||||||
argv++;
|
argv++;
|
||||||
goto process_sig_list;
|
goto process_sig_list;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLE_HUSH_TYPE
|
#if ENABLE_HUSH_TYPE
|
||||||
/* http://www.opengroup.org/onlinepubs/9699919799/utilities/type.html */
|
/* http://www.opengroup.org/onlinepubs/9699919799/utilities/type.html */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue