hush: fixes and small shrink for HUSH_JOB!=y
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
ebc1ee2e2a
commit
75e77deab1
27
shell/hush.c
27
shell/hush.c
@ -805,9 +805,9 @@ struct globals {
|
|||||||
unsigned special_sig_mask;
|
unsigned special_sig_mask;
|
||||||
#if ENABLE_HUSH_JOB
|
#if ENABLE_HUSH_JOB
|
||||||
unsigned fatal_sig_mask;
|
unsigned fatal_sig_mask;
|
||||||
#define G_fatal_sig_mask G.fatal_sig_mask
|
# define G_fatal_sig_mask G.fatal_sig_mask
|
||||||
#else
|
#else
|
||||||
#define G_fatal_sig_mask 0
|
# define G_fatal_sig_mask 0
|
||||||
#endif
|
#endif
|
||||||
char **traps; /* char *traps[NSIG] */
|
char **traps; /* char *traps[NSIG] */
|
||||||
sigset_t pending_set;
|
sigset_t pending_set;
|
||||||
@ -1414,6 +1414,9 @@ static void restore_G_args(save_arg_t *sv, char **argv)
|
|||||||
* Standard says "When a subshell is entered, traps that are not being ignored
|
* Standard says "When a subshell is entered, traps that are not being ignored
|
||||||
* are set to the default actions". bash interprets it so that traps which
|
* are set to the default actions". bash interprets it so that traps which
|
||||||
* are set to '' (ignore) are NOT reset to defaults. We do the same.
|
* are set to '' (ignore) are NOT reset to defaults. We do the same.
|
||||||
|
*
|
||||||
|
* TODO: don't use signal() to install sighandlers: need to mask ALL signals
|
||||||
|
* while handler runs. I saw signal nesting in one strace, race window isn't small.
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
SPECIAL_INTERACTIVE_SIGS = 0
|
SPECIAL_INTERACTIVE_SIGS = 0
|
||||||
@ -1486,12 +1489,13 @@ static sighandler_t pick_sighandler(unsigned sig)
|
|||||||
unsigned sigmask = (1 << sig);
|
unsigned sigmask = (1 << sig);
|
||||||
|
|
||||||
#if ENABLE_HUSH_JOB
|
#if ENABLE_HUSH_JOB
|
||||||
/* sig is fatal? */
|
/* is sig fatal? */
|
||||||
if (G_fatal_sig_mask & sigmask)
|
if (G_fatal_sig_mask & sigmask)
|
||||||
handler = sigexit;
|
handler = sigexit;
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
/* sig has special handling? */
|
/* sig has special handling? */
|
||||||
else if (G.special_sig_mask & sigmask) {
|
if (G.special_sig_mask & sigmask) {
|
||||||
handler = record_pending_signo;
|
handler = record_pending_signo;
|
||||||
/* TTIN/TTOU/TSTP can't be set to record_pending_signo
|
/* TTIN/TTOU/TSTP can't be set to record_pending_signo
|
||||||
* in order to ignore them: they will be raised
|
* in order to ignore them: they will be raised
|
||||||
@ -5604,9 +5608,6 @@ static void re_execute_shell(char ***to_free, const char *s,
|
|||||||
* _inside_ group (just before echo 1), it works.
|
* _inside_ group (just before echo 1), it works.
|
||||||
*
|
*
|
||||||
* I conclude it means we don't need to pass active traps here.
|
* I conclude it means we don't need to pass active traps here.
|
||||||
* Even if we would use signal handlers instead of signal masking
|
|
||||||
* in order to implement trap handling,
|
|
||||||
* exec syscall below resets signals to SIG_DFL for us.
|
|
||||||
*/
|
*/
|
||||||
*pp++ = (char *) "-c";
|
*pp++ = (char *) "-c";
|
||||||
*pp++ = (char *) s;
|
*pp++ = (char *) s;
|
||||||
@ -5623,7 +5624,9 @@ static void re_execute_shell(char ***to_free, const char *s,
|
|||||||
|
|
||||||
do_exec:
|
do_exec:
|
||||||
debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s);
|
debug_printf_exec("re_execute_shell pid:%d cmd:'%s'\n", getpid(), s);
|
||||||
switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
|
/* Don't propagate SIG_IGN to the child */
|
||||||
|
if (SPECIAL_JOBSTOP_SIGS != 0)
|
||||||
|
switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
|
||||||
execve(bb_busybox_exec_path, argv, pp);
|
execve(bb_busybox_exec_path, argv, pp);
|
||||||
/* Fallback. Useful for init=/bin/hush usage etc */
|
/* Fallback. Useful for init=/bin/hush usage etc */
|
||||||
if (argv[0][0] == '/')
|
if (argv[0][0] == '/')
|
||||||
@ -6277,7 +6280,9 @@ static void execvp_or_die(char **argv) NORETURN;
|
|||||||
static void execvp_or_die(char **argv)
|
static void execvp_or_die(char **argv)
|
||||||
{
|
{
|
||||||
debug_printf_exec("execing '%s'\n", argv[0]);
|
debug_printf_exec("execing '%s'\n", argv[0]);
|
||||||
switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
|
/* Don't propagate SIG_IGN to the child */
|
||||||
|
if (SPECIAL_JOBSTOP_SIGS != 0)
|
||||||
|
switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
|
||||||
execvp(argv[0], argv);
|
execvp(argv[0], argv);
|
||||||
bb_perror_msg("can't execute '%s'", argv[0]);
|
bb_perror_msg("can't execute '%s'", argv[0]);
|
||||||
_exit(127); /* bash compat */
|
_exit(127); /* bash compat */
|
||||||
@ -6409,7 +6414,9 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
|
|||||||
# endif
|
# endif
|
||||||
/* Re-exec ourselves */
|
/* Re-exec ourselves */
|
||||||
debug_printf_exec("re-execing applet '%s'\n", argv[0]);
|
debug_printf_exec("re-execing applet '%s'\n", argv[0]);
|
||||||
switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
|
/* Don't propagate SIG_IGN to the child */
|
||||||
|
if (SPECIAL_JOBSTOP_SIGS != 0)
|
||||||
|
switch_off_special_sigs(G.special_sig_mask & SPECIAL_JOBSTOP_SIGS);
|
||||||
execv(bb_busybox_exec_path, argv);
|
execv(bb_busybox_exec_path, argv);
|
||||||
/* If they called chroot or otherwise made the binary no longer
|
/* If they called chroot or otherwise made the binary no longer
|
||||||
* executable, fall through */
|
* executable, fall through */
|
||||||
|
Loading…
Reference in New Issue
Block a user