commit bash-20200707 snapshot

This commit is contained in:
Chet Ramey
2020-07-10 10:08:56 -04:00
parent 9c953962b4
commit 5adc7cd3ec
14 changed files with 75 additions and 54 deletions
+26
View File
@@ -8676,3 +8676,29 @@ lib/readline/vi_mode.c
- rl_vi_{delete,change,yank}_to: if we have a non-null _rl_vimvcxt,
just reinitialize it so we don't have to allocate a new one. This is
a change primarily for callback mode, and fixes a memory leak
builtins/evalstring.c
- optimize_shell_function: try to optimize away the fork in the last
command in a shell function body, under certain conditions
execute_cmd.c
- execute_function: attempt to optimize away forks in a shell function
that is already marked NO_FORK and being executed in a command
substitution
7/8
---
{jobs,nojobs,trap,unwind_prot}.c,lib/malloc/{malloc,table}.c
- interrupt_immediately: remove, no longer used
jobs.c
- waitchld: don't perform asynchronous notification if we are currently
executing a builtin (executing_builtin != 0). Inspired by a report
from Godmar Back <godmar@gmail.com>
7/9
---
lib/readline/signals.c
- _rl_handle_signal: block SIGTTOU while handling a SIGTTOU, since we
no longer run this in a signal handling context where SIGTTOIU would
be blocked
+1
View File
@@ -210,6 +210,7 @@ extern int should_suppress_fork PARAMS((COMMAND *));
extern int can_optimize_connection PARAMS((COMMAND *));
extern void optimize_fork PARAMS((COMMAND *));
extern void optimize_subshell_command PARAMS((COMMAND *));
extern void optimize_shell_function PARAMS((COMMAND *));
/* Functions from evalfile.c */
extern int maybe_execute_file PARAMS((const char *, int));
+21 -1
View File
@@ -145,7 +145,27 @@ optimize_subshell_command (command)
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR))
optimize_subshell_command (command->value.Connection->second);
}
void
optimize_shell_function (command)
COMMAND *command;
{
COMMAND *fc;
fc = (command->type == cm_group) ? command->value.Group->command : command;
if (fc->type == cm_simple && should_suppress_fork (fc))
{
fc->flags |= CMD_NO_FORK;
fc->value.Simple->flags |= CMD_NO_FORK;
}
else if (fc->type == cm_connection && can_optimize_connection (fc) && should_suppress_fork (fc->value.Connection->second))
{
fc->value.Connection->second->flags |= CMD_NO_FORK;
fc->value.Connection->second->value.Simple->flags |= CMD_NO_FORK;
}
}
/* How to force parse_and_execute () to clean up after itself. */
void
parse_and_execute_cleanup (old_running_trap)
+5
View File
@@ -4831,6 +4831,11 @@ execute_function (var, words, flags, fds_to_close, async, subshell)
if (tc && (flags & CMD_IGNORE_RETURN))
tc->flags |= CMD_IGNORE_RETURN;
/* A limited attempt at optimization: shell functions at the end of command
substitutions that are already marked NO_FORK. */
if (tc && (flags & CMD_NO_FORK) && (subshell_environment & SUBSHELL_COMSUB))
optimize_shell_function (tc);
gs = sh_getopt_save_istate ();
if (subshell == 0)
{
+4 -15
View File
@@ -2758,8 +2758,7 @@ wait_sigint_handler (sig)
{
SigHandler *sigint_handler;
if (interrupt_immediately ||
(this_shell_builtin && this_shell_builtin == wait_builtin))
if (this_shell_builtin && this_shell_builtin == wait_builtin)
{
set_exit_status (128+SIGINT);
restore_sigint_handler ();
@@ -2771,20 +2770,12 @@ wait_sigint_handler (sig)
{
trap_handler (SIGINT); /* set pending_traps[SIGINT] */
wait_signal_received = SIGINT;
if (interrupt_immediately && wait_intr_flag)
{
interrupt_immediately = 0;
sh_longjmp (wait_intr_buf, 1);
}
if (wait_intr_flag)
sh_longjmp (wait_intr_buf, 1);
else
/* Let CHECK_WAIT_INTR handle it in wait_for/waitchld */
SIGRETURN (0);
}
else if (interrupt_immediately)
{
ADDINTERRUPT;
QUIT;
}
else /* wait_builtin but signal not trapped, treat as interrupt */
kill (getpid (), SIGINT);
}
@@ -3947,7 +3938,6 @@ itrace("waitchld: waitpid returns %d block = %d children_exited = %d", pid, bloc
{
if (posixly_correct && this_shell_builtin && this_shell_builtin == wait_builtin)
{
interrupt_immediately = 0;
/* This was trap_handler (SIGCHLD) but that can lose traps if
children_exited > 1 */
queue_sigchld_trap (children_exited);
@@ -3978,7 +3968,7 @@ itrace("waitchld: waitpid returns %d block = %d children_exited = %d", pid, bloc
that has just changed state. If we notify asynchronously, and the job
that this process belongs to is no longer running, then notify the user
of that fact now. */
if (asynchronous_notification && interactive)
if (asynchronous_notification && interactive && executing_builtin == 0)
notify_of_job_status ();
return (children_exited);
@@ -4211,7 +4201,6 @@ run_sigchld_trap (nchild)
unwind_protect_int (last_command_exit_value);
unwind_protect_int (last_command_exit_signal);
unwind_protect_var (last_made_pid);
unwind_protect_int (interrupt_immediately);
unwind_protect_int (jobs_list_frozen);
unwind_protect_pointer (the_pipeline);
unwind_protect_pointer (subst_assign_varlist);
+3 -3
View File
@@ -319,7 +319,7 @@ extern char *sbrk ();
#endif /* !HAVE_DECL_SBRK */
#ifdef SHELL
extern int interrupt_immediately, running_trap;
extern int running_trap;
extern int signal_is_trapped PARAMS((int));
#endif
@@ -620,9 +620,9 @@ morecore (nu)
blocked_sigs = 0;
#ifdef SHELL
# if defined (SIGCHLD)
if (interrupt_immediately || running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
if (running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
# else
if (interrupt_immediately || running_trap || signal_is_trapped (SIGINT))
if (running_trap || signal_is_trapped (SIGINT))
# endif
#endif
{
-2
View File
@@ -33,8 +33,6 @@
#include "xmalloc.h"
int interrupt_immediately = 0;
static char xp[64];
main(int c, char **v)
+3 -3
View File
@@ -29,7 +29,7 @@
#include "table.h"
#ifdef SHELL
extern int interrupt_immediately, running_trap;
extern int running_trap;
extern int signal_is_trapped PARAMS((int));
#endif
@@ -174,7 +174,7 @@ mregister_alloc (tag, mem, size, file, line)
/* Block all signals in case we are executed from a signal handler. */
blocked_sigs = 0;
#ifdef SHELL
if (interrupt_immediately || running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
if (running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
#endif
{
_malloc_block_signals (&set, &oset);
@@ -229,7 +229,7 @@ mregister_free (mem, size, file, line)
/* Block all signals in case we are executed from a signal handler. */
blocked_sigs = 0;
#ifdef SHELL
if (interrupt_immediately || running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
if (running_trap || signal_is_trapped (SIGINT) || signal_is_trapped (SIGCHLD))
#endif
{
_malloc_block_signals (&set, &oset);
+5 -3
View File
@@ -219,17 +219,19 @@ _rl_handle_signal (int sig)
#if defined (SIGTSTP)
case SIGTSTP:
case SIGTTIN:
case SIGTTOU:
# if defined (HAVE_POSIX_SIGNALS)
/* Block SIGTTOU so we can restore the terminal settings to something
sane without stopping on SIGTTOU if we have been placed into the
background. Even trying to get the current terminal pgrp with
tcgetpgrp() will generate SIGTTOU, so we don't bother. Don't bother
doing this if we've been stopped on SIGTTOU; it's already too late. */
tcgetpgrp() will generate SIGTTOU, so we don't bother. We still do
this even if we've been stopped on SIGTTOU, since we handle signals
when we have returned from the signal handler and the signal is no
longer blocked. */
sigemptyset (&set);
sigaddset (&set, SIGTTOU);
sigprocmask (SIG_BLOCK, &set, (sigset_t *)NULL);
# endif
case SIGTTOU:
#endif /* SIGTSTP */
case SIGTERM:
#if defined (SIGHUP)
-9
View File
@@ -785,20 +785,11 @@ wait_sigint_handler (sig)
{
last_command_exit_value = 128+SIGINT;
restore_sigint_handler ();
interrupt_immediately = 0;
trap_handler (SIGINT); /* set pending_traps[SIGINT] */
wait_signal_received = SIGINT;
SIGRETURN (0);
}
if (interrupt_immediately)
{
last_command_exit_value = EXECUTION_FAILURE;
restore_sigint_handler ();
ADDINTERRUPT;
QUIT;
}
wait_sigint_received = 1;
SIGRETURN (0);
+3 -3
View File
@@ -1644,9 +1644,9 @@ rewind_input_string ()
/* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS
define, and just use getc/ungetc if it was defined, but since bash
installs its signal handlers without the SA_RESTART flag, some signals
(like SIGCHLD, SIGWINCH, etc.) received during a read(2) will not cause
the read to be restarted. We need to restart it ourselves. */
installs most of its signal handlers without the SA_RESTART flag, some
signals received during a read(2) will not cause the read to be restarted.
We will need to restart it ourselves. */
static int
yy_stream_get ()
+2 -2
View File
@@ -526,7 +526,6 @@ termsig_sighandler (sig)
terminating_signal = sig;
/* XXX - should this also trigger when interrupt_immediately is set? */
if (terminate_immediately)
{
#if defined (HISTORY)
@@ -669,7 +668,8 @@ sigint_sighandler (sig)
wait_signal_received = sig;
SIGRETURN (0);
}
/* This is no longer used, but this code block remains as a reminder. */
if (interrupt_immediately)
{
interrupt_immediately = 0;
+1 -4
View File
@@ -499,13 +499,10 @@ trap_handler (sig)
/* Set the event hook so readline will call it after the signal handlers
finish executing, so if this interrupted character input we can get
quick response. */
if (RL_ISSTATE (RL_STATE_SIGHANDLER) && interrupt_immediately == 0)
if (RL_ISSTATE (RL_STATE_SIGHANDLER))
bashline_set_event_hook ();
#endif
if (interrupt_immediately)
run_pending_traps ();
errno = oerrno;
}
+1 -9
View File
@@ -108,21 +108,13 @@ uwp_init ()
}
/* Run a function without interrupts. This relies on the fact that the
FUNCTION cannot change the value of interrupt_immediately. (I.e., does
not call QUIT (). */
FUNCTION cannot call QUIT (). */
static void
without_interrupts (function, arg1, arg2)
VFunction *function;
char *arg1, *arg2;
{
int old_interrupt_immediately;
old_interrupt_immediately = interrupt_immediately;
interrupt_immediately = 0;
(*function)(arg1, arg2);
interrupt_immediately = old_interrupt_immediately;
}
/* Start the beginning of a region. */