mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-02 18:00:49 +02:00
commit bash-20200707 snapshot
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
@@ -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
|
||||
{
|
||||
|
||||
@@ -33,8 +33,6 @@
|
||||
|
||||
#include "xmalloc.h"
|
||||
|
||||
int interrupt_immediately = 0;
|
||||
|
||||
static char xp[64];
|
||||
|
||||
main(int c, char **v)
|
||||
|
||||
+3
-3
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user