summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2020-04-08 17:09:56 -0400
committerChet Ramey <chet.ramey@case.edu>2020-04-08 17:09:56 -0400
commitea31c00845c858098d232bd014bf27b5a63a668b (patch)
tree20debaadb45cae9571cca0aa0b8fd62d44575c68
parente34adc2c3b6b8722d0316f3b26fe5346faf94dea (diff)
downloadbash-ea31c00845c858098d232bd014bf27b5a63a668b.tar.gz
commit bash-20200406 snapshot
-rw-r--r--CWRU/CWRU.chlog59
-rw-r--r--bashline.c21
-rw-r--r--execute_cmd.c7
-rw-r--r--jobs.c40
-rw-r--r--lib/readline/display.c204
-rw-r--r--lib/readline/kill.c2
-rw-r--r--lib/readline/readline.c2
-rw-r--r--nojobs.c21
-rw-r--r--sig.c7
-rwxr-xr-xtests/RUN-ONE-TEST2
-rw-r--r--trap.c2
11 files changed, 266 insertions, 101 deletions
diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog
index 8173ffe..49067d9 100644
--- a/CWRU/CWRU.chlog
+++ b/CWRU/CWRU.chlog
@@ -7862,3 +7862,62 @@ builtins/fc.def
<ami@fischman.org>; originally raised by Boruch Baum
<boruch_baum@gmx.com> back in 10/2017
+ 4/6
+ ---
+lib/readline/display.c
+ - puts_face,putc_face: new functions to write strings or characters to
+ the display while handling standout mode
+ - update_line,_rl_move_cursor_relative: take additional argument(s)
+ describing the visible and invisible faces corresponding to the
+ visible and invisible lines, respectively
+
+lib/readline/readline.c
+ - _rl_enable_bracketed_paste: for the time being, initialize to 1 (on
+ by default)
+
+trap.c
+ - run_interrupt_trap: set pending_sigs[SIGINT] and catch_flag to 0
+ since run_pending_trap usually does these things
+
+sig.c
+ - throw_to_top_level: only call the SIGINT trap if there is a SIGINT
+ trap pending (shouldn't matter, just a check)
+
+bashline.c
+ - bash_event_hook: try to identify the signal of interest we've
+ received
+ - bash_event_hook: if in posix mode running the read builtin, and we
+ get a (trappped) SIGINT, throw to top level so we can interrupt
+ the read. From a report by Robert Elz <kre@munnari.oz.au>
+
+ 4/7
+ ---
+lib/readline/display.c
+ - update_line: make sure to update and compare face data at the same
+ time as comparing old and new line data: the lines are only the same
+ if the face information and character information are identical
+ (ofd, ols, etc.)
+ - update_line: make sure to copy face data along with line data
+ - update_line: use puts_face in place of _rl_output_some_chars to
+ output face data along with line data
+ - _rl_move_cursor_relative: when we write characters, make sure to take
+ the face data into account using puts_face
+ [END OF INTEGRATION OF ACTIVE MARK AND FACE PATCHES from
+ Daniel Colascione <dancol@google.com>]
+
+{jobs,nojobs}.c
+ - make_child: to avoid installing a handler for SIGTERM in interactive
+ shells, and avoid race conditions with child processes resetting the
+ SIGTERM signal handler to the default, block SIGTERM and then
+ reset the SIGTERM handler to SIG_DFL before fork, then reset the
+ handler to SIG_IGN and unblock it in the parent after fork() returns.
+ Fix for readline and SIGTERM handling reported by Chris Down
+ <chris@chrisdown.name> (original change was back in 2/2013) that
+ allows a bash waiting in readline() for input to be killed with a
+ SIGTERM sent by another process
+ - take out calls to RESET_SIGTERM, no longer needed
+
+execute_cmd.c
+ - execute_in_subshell,execute_simple_command,execute_disk_command:
+ remove calls to CHECK_SIGTERM, since we don't install a handler
+ any more
diff --git a/bashline.c b/bashline.c
index 0b72fed..e089d1b 100644
--- a/bashline.c
+++ b/bashline.c
@@ -62,6 +62,7 @@
#endif
#include "builtins/common.h"
+#include "builtins/builtext.h" /* for read_builtin */
#include <readline/rlconf.h>
#include <readline/readline.h>
@@ -4657,6 +4658,8 @@ bash_dequote_text (text)
static int
bash_event_hook ()
{
+ int sig;
+
/* XXX - see if we need to do anything here if sigterm_received == 1,
we probably don't want to reset the event hook since we will not be
jumping to the top level */
@@ -4666,6 +4669,16 @@ bash_event_hook ()
return 0;
}
+ sig = 0;
+ if (terminating_signal)
+ sig = terminating_signal;
+ else if (interrupt_state)
+ sig = SIGINT;
+ else if (sigalrm_seen)
+ sig = SIGALRM;
+ else
+ sig = first_pending_trap ();
+
/* If we're going to longjmp to top_level, make sure we clean up readline.
check_signals will call QUIT, which will eventually longjmp to top_level,
calling run_interrupt_trap along the way. The check for sigalrm_seen is
@@ -4673,6 +4686,14 @@ bash_event_hook ()
if (terminating_signal || interrupt_state || sigalrm_seen)
rl_cleanup_after_signal ();
bashline_reset_event_hook ();
+
+ /* posix mode SIGINT during read -e. We only get here if SIGINT is trapped. */
+ if (posixly_correct && this_shell_builtin == read_builtin && sig == 2)
+ {
+ last_command_exit_value = 128|SIGINT;
+ throw_to_top_level ();
+ }
+
check_signals_and_traps (); /* XXX */
return 0;
}
diff --git a/execute_cmd.c b/execute_cmd.c
index d7fa5c6..3b40e80 100644
--- a/execute_cmd.c
+++ b/execute_cmd.c
@@ -1518,7 +1518,6 @@ execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close)
QUIT;
CHECK_TERMSIG;
- CHECK_SIGTERM; /* after RESET_SIGTERM in make_child */
reset_terminating_signals (); /* in sig.c */
/* Cancel traps, in trap.c. */
@@ -4274,8 +4273,6 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
last_asynchronous_pid = old_last_async_pid;
- CHECK_SIGTERM;
-
if (async)
subshell_level++; /* not for pipes yet */
@@ -5393,8 +5390,6 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
/* Cancel traps, in trap.c. */
restore_original_signals ();
- CHECK_SIGTERM;
-
#if defined (JOB_CONTROL)
FREE (p);
#endif
@@ -5468,8 +5463,6 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
exit (execute_shell_function (hookf, wl));
}
- CHECK_SIGTERM;
-
/* Execve expects the command name to be in args[0]. So we
leave it there, in the same format that the user used to
type it in. */
diff --git a/jobs.c b/jobs.c
index f7a0d67..6bc5f2a 100644
--- a/jobs.c
+++ b/jobs.c
@@ -2123,17 +2123,28 @@ make_child (command, async_p)
int async_p;
{
int forksleep;
- sigset_t set, oset;
+ sigset_t set, oset, termset, chldset, oset_copy;
pid_t pid;
+ SigHandler *oterm;
+
+ sigemptyset (&oset_copy);
+ sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &oset_copy);
+ sigaddset (&oset_copy, SIGTERM);
- /* XXX - block SIGTERM here and unblock in child after fork resets the
- set of pending signals? */
+ /* Block SIGTERM here and unblock in child after fork resets the
+ set of pending signals. */
sigemptyset (&set);
sigaddset (&set, SIGCHLD);
sigaddset (&set, SIGINT);
+ sigaddset (&set, SIGTERM);
+
sigemptyset (&oset);
sigprocmask (SIG_BLOCK, &set, &oset);
+ /* Blocked in the parent, child will receive it after unblocking SIGTERM */
+ if (interactive_shell)
+ oterm = set_signal_handler (SIGTERM, SIG_DFL);
+
making_children ();
forksleep = 1;
@@ -2148,19 +2159,17 @@ make_child (command, async_p)
sync_buffered_stream (default_buffered_input);
#endif /* BUFFERED_INPUT */
- RESET_SIGTERM;
-
/* Create the child, handle severe errors. Retry on EAGAIN. */
while ((pid = fork ()) < 0 && errno == EAGAIN && forksleep < FORKSLEEP_MAX)
{
/* bash-4.2 */
- sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
+ /* keep SIGTERM blocked until we reset the handler to SIG_IGN */
+ sigprocmask (SIG_SETMASK, &oset_copy, (sigset_t *)NULL);
/* If we can't create any children, try to reap some dead ones. */
waitchld (-1, 0);
errno = EAGAIN; /* restore errno */
sys_error ("fork: retry");
- RESET_SIGTERM;
if (sleep (forksleep) != 0)
break;
@@ -2172,7 +2181,8 @@ make_child (command, async_p)
}
if (pid != 0)
- RESET_SIGTERM;
+ if (interactive_shell)
+ set_signal_handler (SIGTERM, oterm);
if (pid < 0)
{
@@ -2208,7 +2218,7 @@ make_child (command, async_p)
CLRINTERRUPT; /* XXX - children have their own interrupt state */
- /* Restore top-level signal mask. */
+ /* Restore top-level signal mask, including unblocking SIGTERM */
restore_sigmask ();
if (job_control)
@@ -2271,12 +2281,8 @@ make_child (command, async_p)
sh_closepipe (pgrp_pipe);
#endif /* PGRP_PIPE */
-#if 0
/* Don't set last_asynchronous_pid in the child */
- if (async_p)
- last_asynchronous_pid = mypid; /* XXX */
- else
-#endif
+
#if defined (RECYCLES_PIDS)
if (last_asynchronous_pid == mypid)
/* Avoid pid aliasing. 1 seems like a safe, unusual pid value. */
@@ -2335,9 +2341,9 @@ make_child (command, async_p)
js.c_totforked++;
js.c_living++;
- /* Unblock SIGINT and SIGCHLD unless creating a pipeline, in which case
- SIGCHLD remains blocked until all commands in the pipeline have been
- created. */
+ /* Unblock SIGTERM, SIGINT, and SIGCHLD unless creating a pipeline, in
+ which case SIGCHLD remains blocked until all commands in the pipeline
+ have been created (execute_cmd.c:execute_pipeline()). */
sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
}
diff --git a/lib/readline/display.c b/lib/readline/display.c
index 855baf6..14af1e9 100644
--- a/lib/readline/display.c
+++ b/lib/readline/display.c
@@ -63,14 +63,17 @@
extern char *strchr (), *strrchr ();
#endif /* !strchr && !__STDC__ */
-static void update_line PARAMS((char *, char *, int, int, int, int));
+static void putc_face PARAMS((int, int, char *));
+static void puts_face PARAMS((const char *, const char *, int));
+
+static void update_line PARAMS((char *, char *, char *, char *, int, int, int, int));
static void space_to_eol PARAMS((int));
static void delete_chars PARAMS((int));
static void insert_some_chars PARAMS((char *, int, int));
static void open_some_spaces PARAMS((int));
static void cr PARAMS((void));
static void redraw_prompt PARAMS((char *));
-static void _rl_move_cursor_relative PARAMS((int, const char *));
+static void _rl_move_cursor_relative PARAMS((int, const char *, const char *));
/* Values for FLAGS */
#define PMT_MULTILINE 0x01
@@ -828,10 +831,8 @@ rl_redisplay (void)
_rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
if (local_prompt_len > 0)
- {
- invis_adds (&out, local_prompt, local_prompt_len, cur_face);
- invis_nul (&out);
- }
+ invis_adds (&out, local_prompt, local_prompt_len, cur_face);
+ invis_nul (&out);
wrap_offset = local_prompt_len - prompt_visible_length;
}
else
@@ -994,6 +995,11 @@ rl_redisplay (void)
for (in = 0; in < rl_end; in++)
#endif
{
+ if (in == hl_begin)
+ cur_face = FACE_STANDOUT;
+ else if (in == hl_end)
+ cur_face = FACE_NORMAL;
+
c = (unsigned char)rl_line_buffer[in];
#if defined (HANDLE_MULTIBYTE)
@@ -1229,11 +1235,11 @@ rl_redisplay (void)
#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
-#define VIS_FACE(line) (visible_face + vis_lbreaks[line]);
+#define VIS_FACE(line) (vis_face + vis_lbreaks[line])
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
#define VIS_LINE_FACE(line) ((line) > _rl_vis_botlin) ? "" : VIS_FACE(line)
#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
-#define INV_LINE_FACE(line) (invisible_face + inv_lbreaks[line])
+#define INV_LINE_FACE(line) (inv_face + inv_lbreaks[line])
#define OLD_CPOS_IN_PROMPT() (cpos_adjusted == 0 && \
_rl_last_c_pos != o_cpos && \
@@ -1247,7 +1253,9 @@ rl_redisplay (void)
the locale from a non-multibyte to a multibyte one. */
o_cpos = _rl_last_c_pos;
cpos_adjusted = 0;
- update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
+ update_line (VIS_LINE(linenum), VIS_LINE_FACE(linenum),
+ INV_LINE(linenum), INV_LINE_FACE(linenum),
+ linenum,
VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
/* update_line potentially changes _rl_last_c_pos, but doesn't
@@ -1338,7 +1346,7 @@ rl_redisplay (void)
{
tt = VIS_CHARS (linenum);
_rl_move_vert (linenum);
- _rl_move_cursor_relative (0, tt);
+ _rl_move_cursor_relative (0, tt, VIS_FACE(linenum));
_rl_clear_to_eol
((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
}
@@ -1370,11 +1378,7 @@ rl_redisplay (void)
/* XXX - why not use local_prompt_len? */
nleft = prompt_visible_length + wrap_offset;
if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
-#if 0
- _rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt)
-#else
_rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
-#endif
{
_rl_cr ();
if (modmark)
@@ -1422,9 +1426,9 @@ rl_redisplay (void)
point specified by a buffer position (NLEFT) that doesn't take
invisible characters into account. */
if (mb_cur_max > 1 && rl_byte_oriented == 0)
- _rl_move_cursor_relative (nleft, &invisible_line[pos]);
+ _rl_move_cursor_relative (nleft, &invisible_line[pos], &inv_face[pos]);
else if (nleft != _rl_last_c_pos)
- _rl_move_cursor_relative (nleft, &invisible_line[pos]);
+ _rl_move_cursor_relative (nleft, &invisible_line[pos], &inv_face[pos]);
}
}
else /* Do horizontal scrolling. Much simpler */
@@ -1495,8 +1499,8 @@ rl_redisplay (void)
forced_display = 0;
o_cpos = _rl_last_c_pos;
cpos_adjusted = 0;
- update_line (&visible_line[last_lmargin],
- &invisible_line[lmargin],
+ update_line (&visible_line[last_lmargin], &vis_face[last_lmargin],
+ &invisible_line[lmargin], &inv_face[lmargin],
0,
_rl_screenwidth + visible_wrap_offset,
_rl_screenwidth + (lmargin ? 0 : wrap_offset),
@@ -1521,7 +1525,7 @@ rl_redisplay (void)
if (visible_first_line_len > _rl_screenwidth)
visible_first_line_len = _rl_screenwidth;
- _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]);
+ _rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin], &inv_face[lmargin]);
last_lmargin = lmargin;
}
}
@@ -1550,18 +1554,50 @@ rl_redisplay (void)
_rl_release_sigint ();
}
+static void
+putc_face (int c, int face, char *cur_face)
+{
+ char cf;
+ cf = *cur_face;
+ if (cf != face)
+ {
+ if (cf != FACE_NORMAL && cf != FACE_STANDOUT)
+ return;
+ if (face != FACE_NORMAL && face != FACE_STANDOUT)
+ return;
+ if (face == FACE_STANDOUT && cf == FACE_NORMAL)
+ _rl_standout_on ();
+ if (face == FACE_NORMAL && cf == FACE_STANDOUT)
+ _rl_standout_off ();
+ *cur_face = face;
+ }
+ if (c != EOF)
+ putc (c, rl_outstream);
+}
+
+static void
+puts_face (const char *str, const char *face, int n)
+{
+ int i;
+ char cur_face;
+
+ for (cur_face = FACE_NORMAL, i = 0; i < n; i++)
+ putc_face (str[i], face[i], &cur_face);
+ putc_face (EOF, FACE_NORMAL, &cur_face);
+}
+
#define ADJUST_CPOS(x) do { _rl_last_c_pos -= (x) ; cpos_adjusted = 1; } while (0)
/* PWP: update_line() is based on finding the middle difference of each
line on the screen; vis:
/old first difference
- /beginning of line | /old last same /old EOL
- v v v v
+ /beginning of line | /old last same /old EOL
+ v v v v
old: eddie> Oh, my little gruntle-buggy is to me, as lurgid as
new: eddie> Oh, my little buggy says to me, as lurgid as
- ^ ^ ^ ^
- \beginning of line | \new last same \new end of line
+ ^ ^ ^ ^
+ \beginning of line | \new last same \new end of line
\new first difference
All are character pointers for the sake of speed. Special cases for
@@ -1569,9 +1605,10 @@ new: eddie> Oh, my little buggy says to me, as lurgid as
Could be made even smarter, but this works well enough */
static void
-update_line (char *old, char *new, int current_line, int omax, int nmax, int inv_botlin)
+update_line (char *old, char *old_face, char *new, char *new_face, int current_line, int omax, int nmax, int inv_botlin)
{
- register char *ofd, *ols, *oe, *nfd, *nls, *ne;
+ char *ofd, *ols, *oe, *nfd, *nls, *ne;
+ char *ofdf, *nfdf, *olsf, *nlsf;
int temp, lendiff, wsatend, od, nd, twidth, o_cpos;
int current_invis_chars;
int col_lendiff, col_temp;
@@ -1706,7 +1743,7 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
int count, i, j;
char *optr;
- _rl_output_some_chars (new, newbytes);
+ puts_face (new, new_face, newbytes);
_rl_last_c_pos = newwidth;
_rl_last_v_pos++;
@@ -1734,8 +1771,12 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
/* Don't bother trying to fit the bytes if the number of bytes
doesn't change. */
if (oldbytes != newbytes)
- memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes) + 1);
+ {
+ memmove (old+newbytes, old+oldbytes, strlen (old+oldbytes) + 1);
+ memmove (old_face+newbytes, old_face+oldbytes, strlen (old+oldbytes) + 1);
+ }
memcpy (old, new, newbytes);
+ memcpy (old_face, new_face, newbytes);
j = newbytes - oldbytes;
omax += j;
/* Fix up indices if we copy data from one line to another */
@@ -1749,20 +1790,26 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
_rl_last_c_pos = 1;
_rl_last_v_pos++;
if (old[0] && new[0])
- old[0] = new[0];
+ {
+ old[0] = new[0];
+ old_face[0] = new_face[0];
+ }
}
}
else
#endif
{
if (new[0])
- putc (new[0], rl_outstream);
+ puts_face (new, new_face, 1);
else
putc (' ', rl_outstream);
_rl_last_c_pos = 1;
_rl_last_v_pos++;
if (old[0] && new[0])
- old[0] = new[0];
+ {
+ old[0] = new[0];
+ old_face[0] = new_face[0];
+ }
}
}
@@ -1770,11 +1817,13 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
if (_rl_quick_redisplay)
{
nfd = new;
+ nfdf = new_face;
ofd = old;
+ ofdf = old_face;
for (od = 0, oe = ofd; od < omax && *oe; oe++, od++);
for (nd = 0, ne = nfd; nd < nmax && *ne; ne++, nd++);
od = nd = 0;
- _rl_move_cursor_relative (0, old);
+ _rl_move_cursor_relative (0, old, old_face);
bytes_to_insert = ne - nfd;
if (bytes_to_insert < local_prompt_len) /* ??? */
@@ -1790,7 +1839,7 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
bytes_to_insert -= local_prompt_len;
if (bytes_to_insert > 0)
{
- _rl_output_some_chars (new+local_prompt_len, bytes_to_insert);
+ puts_face (new+local_prompt_len, nfdf+local_prompt_len, bytes_to_insert);
if (mb_cur_max > 1 && rl_byte_oriented)
_rl_last_c_pos += _rl_col_width (new, local_prompt_len, ne-new, 1);
else
@@ -1813,11 +1862,13 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
/* See if the old line is a subset of the new line, so that the
only change is adding characters. */
temp = (omax < nmax) ? omax : nmax;
- if (memcmp (old, new, temp) == 0) /* adding at the end */
+ if (memcmp (old, new, temp) == 0 && memcmp (old_face, new_face, temp) == 0)
{
- new_offset = old_offset = temp;
+ new_offset = old_offset = temp; /* adding at the end */
ofd = old + temp;
+ ofdf = old_face + temp;
nfd = new + temp;
+ nfdf = new_face + temp;
}
else
{
@@ -1825,36 +1876,42 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
memset (&ps_old, 0, sizeof(mbstate_t));
/* Are the old and new lines the same? */
- if (omax == nmax && memcmp (new, old, omax) == 0)
+ if (omax == nmax && memcmp (new, old, omax) == 0 && memcmp (new_face, old_face, omax) == 0)
{
old_offset = omax;
new_offset = nmax;
ofd = old + omax;
+ ofdf = old_face + omax;
nfd = new + nmax;
+ nfdf = new_face + nmax;
}
else
{
/* Go through the line from the beginning and find the first
- difference. */
+ difference. We assume that faces change at (possibly multi-
+ byte) character boundaries. */
new_offset = old_offset = 0;
- for (ofd = old, nfd = new;
+ for (ofd = old, ofdf = old_face, nfd = new, nfdf = new_face;
(ofd - old < omax) && *ofd &&
- _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
+ _rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new) &&
+ *ofdf == *nfdf; )
{
old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
ofd = old + old_offset;
+ ofdf = old_face + old_offset;
nfd = new + new_offset;
+ nfdf = new_face + new_offset;
}
}
}
}
else
#endif
- for (ofd = old, nfd = new;
- (ofd - old < omax) && *ofd && (*ofd == *nfd);
- ofd++, nfd++)
+ for (ofd = old, ofdf = old_face, nfd = new, nfdf = new_face;
+ (ofd - old < omax) && *ofd && (*ofd == *nfd) && (*ofdf == *nfdf);
+ ofd++, nfd++, ofdf++, nfdf++)
;
/* Move to the end of the screen line. ND and OD are used to keep track
@@ -1883,7 +1940,9 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
old_offset = _rl_find_prev_mbchar (old, ofd - old, MB_FIND_ANY);
new_offset = _rl_find_prev_mbchar (new, nfd - new, MB_FIND_ANY);
ofd = old + old_offset; /* equal by definition */
+ ofdf = old_face + old_offset;
nfd = new + new_offset;
+ nfdf = new_face + new_offset;
}
}
#endif
@@ -1896,34 +1955,41 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
ols = old + _rl_find_prev_mbchar (old, oe - old, MB_FIND_ANY);
+ olsf = old_face + (ols - old);
nls = new + _rl_find_prev_mbchar (new, ne - new, MB_FIND_ANY);
+ nlsf = new_face + (nls - new);
while ((ols > ofd) && (nls > nfd))
{
memset (&ps_old, 0, sizeof (mbstate_t));
memset (&ps_new, 0, sizeof (mbstate_t));
- if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
+ if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0 ||
+ *olsf != *nlsf)
break;
if (*ols == ' ')
wsatend = 0;
ols = old + _rl_find_prev_mbchar (old, ols - old, MB_FIND_ANY);
+ olsf = old_face + (ols - old);
nls = new + _rl_find_prev_mbchar (new, nls - new, MB_FIND_ANY);
+ nlsf = new_face + (nls - new);
}
}
else
{
#endif /* HANDLE_MULTIBYTE */
ols = oe - 1; /* find last same */
+ olsf = old_face + (ols - old);
nls = ne - 1;
- while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
+ nlsf = new_face + (nls - new);
+ while ((ols > ofd) && (nls > nfd) && (*ols == *nls) && (*olsf == *nlsf))
{
if (*ols != ' ')
wsatend = 0;
- ols--;
- nls--;
+ ols--; olsf--;
+ nls--; nlsf--;
}
#if defined (HANDLE_MULTIBYTE)
}
@@ -1932,15 +1998,17 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
if (wsatend)
{
ols = oe;
+ olsf = old_face + (ols - old);
nls = ne;
+ nlsf = new_face + (nls - new);
}
#if defined (HANDLE_MULTIBYTE)
/* This may not work for stateful encoding, but who cares? To handle
stateful encoding properly, we have to scan each string from the
beginning and compare. */
- else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0)
+ else if (_rl_compare_chars (ols, 0, NULL, nls, 0, NULL) == 0 || *olsf != *nlsf)
#else
- else if (*ols != *nls)
+ else if (*ols != *nls || *olsf != *nlsf)
#endif
{
if (*ols) /* don't step past the NUL */
@@ -1957,6 +2025,8 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
else
nls++;
}
+ olsf = old_face + (ols - old);
+ nlsf = new_face + (nls - new);
}
/* count of invisible characters in the current invisible line. */
@@ -2049,6 +2119,7 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv
if ((od <= prompt_last_invisible || nd <= prompt_last_invisible))
{
nfd = new + lendiff; /* number of characters we output above */
+ nfdf = new_face + lendiff;
nd = lendiff;
/* Do a dumb update and return */
@@ -2056,7 +2127,7 @@ dumb_update:
temp = ne - nfd;
if (temp > 0)
{
- _rl_output_some_chars (nfd, temp);
+ puts_face (nfd, nfdf, temp);
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
_rl_last_c_pos += _rl_col_width (new, nd, ne - new, 1);
@@ -2107,7 +2178,7 @@ dumb_update:
/* When this function returns, _rl_last_c_pos is correct, and an absolute
cursor position in multibyte mode, but a buffer index when not in a
multibyte locale. */
- _rl_move_cursor_relative (od, old);
+ _rl_move_cursor_relative (od, old, old_face);
#if defined (HANDLE_MULTIBYTE)
/* We need to indicate that the cursor position is correct in the presence of
@@ -2166,6 +2237,9 @@ dumb_update:
: _rl_col_width (new, 0, nls - new, 1);
/* if we changed nls and ols, we need to recompute lendiff */
lendiff = (nls - nfd) - (ols - ofd);
+
+ nlsf = new_face + (nls - new);
+ olsf = old_face + (ols - old);
}
else
newwidth = _rl_col_width (new, nfd - new, nls - new, 1);
@@ -2233,7 +2307,7 @@ dumb_update:
only happen in a multibyte environment. */
if (lendiff < 0)
{
- _rl_output_some_chars (nfd, temp);
+ puts_face (nfd, nfdf, temp);
_rl_last_c_pos += col_temp;
/* If nfd begins before any invisible characters in the prompt,
adjust _rl_last_c_pos to account for wrap_offset and set
@@ -2267,7 +2341,7 @@ dumb_update:
(visible_wrap_offset >= current_invis_chars))
{
open_some_spaces (col_lendiff);
- _rl_output_some_chars (nfd, bytes_to_insert);
+ puts_face (nfd, nfdf, bytes_to_insert);
if (mb_cur_max > 1 && rl_byte_oriented == 0)
_rl_last_c_pos += _rl_col_width (nfd, 0, bytes_to_insert, 1);
else
@@ -2277,13 +2351,13 @@ dumb_update:
{
/* At the end of a line the characters do not have to
be "inserted". They can just be placed on the screen. */
- _rl_output_some_chars (nfd, temp);
+ puts_face (nfd, nfdf, temp);
_rl_last_c_pos += col_temp;
return;
}
else /* just write from first difference to end of new line */
{
- _rl_output_some_chars (nfd, temp);
+ puts_face (nfd, nfdf, temp);
_rl_last_c_pos += col_temp;
/* If nfd begins before the last invisible character in the
prompt, adjust _rl_last_c_pos to account for wrap_offset
@@ -2305,7 +2379,7 @@ dumb_update:
else
{
/* cannot insert chars, write to EOL */
- _rl_output_some_chars (nfd, temp);
+ puts_face (nfd, nfdf, temp);
_rl_last_c_pos += col_temp;
/* If we're in a multibyte locale and were before the last invisible
char in the current line (which implies we just output some invisible
@@ -2359,7 +2433,7 @@ dumb_update:
characters in the prompt, we need to adjust _rl_last_c_pos
in a multibyte locale to account for the wrap offset and
set cpos_adjusted accordingly. */
- _rl_output_some_chars (nfd, bytes_to_insert);
+ puts_face (nfd, nfdf, bytes_to_insert);
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
/* This still doesn't take into account whether or not the
@@ -2393,7 +2467,7 @@ dumb_update:
so we move there with _rl_move_cursor_relative */
if (_rl_horizontal_scroll_mode && ((oe-old) > (ne-new)))
{
- _rl_move_cursor_relative (ne-new, new);
+ _rl_move_cursor_relative (ne-new, new, new_face);
goto clear_rest_of_line;
}
}
@@ -2407,7 +2481,7 @@ dumb_update:
characters in the prompt, we need to adjust _rl_last_c_pos
in a multibyte locale to account for the wrap offset and
set cpos_adjusted accordingly. */
- _rl_output_some_chars (nfd, temp);
+ puts_face (nfd, nfdf, temp);
_rl_last_c_pos += col_temp; /* XXX */
if (mb_cur_max > 1 && rl_byte_oriented == 0)
{
@@ -2578,7 +2652,7 @@ rl_redraw_prompt_last_line (void)
the movement is being done.
DATA is always the visible line or the invisible line */
static void
-_rl_move_cursor_relative (int new, const char *data)
+_rl_move_cursor_relative (int new, const char *data, const char *dataf)
{
register int i;
int woff; /* number of invisible chars on current line */
@@ -2708,13 +2782,11 @@ _rl_move_cursor_relative (int new, const char *data)
else
{
_rl_cr ();
- for (i = 0; i < new; i++)
- putc (data[i], rl_outstream);
+ puts_face (data, dataf, new);
}
}
else
- for (i = cpos; i < new; i++)
- putc (data[i], rl_outstream);
+ puts_face (data + cpos, dataf + cpos, new - cpos);
}
#if defined (HANDLE_MULTIBYTE)
@@ -3189,7 +3261,7 @@ _rl_update_final (void)
/* If we've wrapped lines, remove the final xterm line-wrap flag. */
if (full_lines && _rl_term_autowrap && botline_length == _rl_screenwidth)
{
- char *last_line;
+ char *last_line, *last_face;
/* LAST_LINE includes invisible characters, so if you want to get the
last character of the first line, you have to take WOFF into account.
@@ -3197,10 +3269,12 @@ _rl_update_final (void)
which takes a buffer position as the first argument, and any direct
subscripts of LAST_LINE. */
last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]]; /* = VIS_CHARS(_rl_vis_botlin); */
+ last_face = &vis_face[vis_lbreaks[_rl_vis_botlin]]; /* = VIS_CHARS(_rl_vis_botlin); */
cpos_buffer_position = -1; /* don't know where we are in buffer */
- _rl_move_cursor_relative (_rl_screenwidth - 1 + woff, last_line); /* XXX */
+ _rl_move_cursor_relative (_rl_screenwidth - 1 + woff, last_line, last_face); /* XXX */
_rl_clear_to_eol (0);
- putc (last_line[_rl_screenwidth - 1 + woff], rl_outstream);
+ puts_face (&last_line[_rl_screenwidth - 1 + woff],
+ &last_face[_rl_screenwidth - 1 + woff], 1);
}
_rl_vis_botlin = 0;
if (botline_length > 0 || _rl_last_c_pos > 0)
diff --git a/lib/readline/kill.c b/lib/readline/kill.c
index 16cbc46..e65e988 100644
--- a/lib/readline/kill.c
+++ b/lib/readline/kill.c
@@ -718,7 +718,7 @@ _rl_bracketed_text (size_t *lenp)
/* Having read the special escape sequence denoting the beginning of a
`bracketed paste' sequence, read the rest of the pasted input until the
closing sequence and insert the pasted text as a single unit without
- interpretation. */
+ interpretation. Temporarily highlight the inserted text. */
int
rl_bracketed_paste_begin (int count, int key)
{
diff --git a/lib/readline/readline.c b/lib/readline/readline.c
index d18ab7c..9f9929f 100644
--- a/lib/readline/readline.c
+++ b/lib/readline/readline.c
@@ -314,7 +314,7 @@ int _rl_show_mode_in_prompt = 0;
/* Non-zero means to attempt to put the terminal in `bracketed paste mode',
where it will prefix pasted text with an escape sequence and send
another to mark the end of the paste. */
-int _rl_enable_bracketed_paste = 0;
+int _rl_enable_bracketed_paste = 1; /* XXX - for now */
/* **************************************************************** */
/* */
diff --git a/nojobs.c b/nojobs.c
index 53367bd..a2b17be 100644
--- a/nojobs.c
+++ b/nojobs.c
@@ -496,6 +496,7 @@ make_child (command, async_p)
{
pid_t pid;
int forksleep;
+ sigset_t set, oset;
/* Discard saved memory. */
if (command)
@@ -512,16 +513,22 @@ make_child (command, async_p)
sync_buffered_stream (default_buffered_input);
#endif /* BUFFERED_INPUT */
- /* XXX - block SIGTERM here and unblock in child after fork resets the
- set of pending signals? */
- RESET_SIGTERM;
+ /* Block SIGTERM here and unblock in child after fork resets the
+ set of pending signals */
+ if (interactive_shell)
+ {
+ sigemptyset (&set);
+ sigaddset (&set, SIGTERM);
+ sigemptyset (&oset);
+ sigprocmask (SIG_BLOCK, &set, &oset);
+ set_signal_handler (SIGTERM, SIG_DFL);
+ }
/* Create the child, handle severe errors. Retry on EAGAIN. */
forksleep = 1;
while ((pid = fork ()) < 0 && errno == EAGAIN && forksleep < FORKSLEEP_MAX)
{
sys_error ("fork: retry");
- RESET_SIGTERM;
#if defined (HAVE_WAITPID)
/* Posix systems with a non-blocking waitpid () system call available
@@ -537,7 +544,11 @@ make_child (command, async_p)
}
if (pid != 0)
- RESET_SIGTERM;
+ if (interactive_shell)
+ {
+ set_signal_handler (SIGTERM, SIG_IGN);
+ sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
+ }
if (pid < 0)
{
diff --git a/sig.c b/sig.c
index c0107d9..54bf7d7 100644
--- a/sig.c
+++ b/sig.c
@@ -1,6 +1,6 @@
/* sig.c - interface for shell signal handlers and signal initialization. */
-/* Copyright (C) 1994-2019 Free Software Foundation, Inc.
+/* Copyright (C) 1994-2020 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -324,8 +324,7 @@ initialize_shell_signals ()
{
set_signal_handler (SIGINT, sigint_sighandler);
get_original_signal (SIGTERM);
- if (signal_is_hard_ignored (SIGTERM) == 0)
- set_signal_handler (SIGTERM, sigterm_sighandler);
+ set_signal_handler (SIGTERM, SIG_IGN);
set_sigwinch_handler ();
}
}
@@ -412,7 +411,7 @@ throw_to_top_level ()
set_pipestatus_from_exit (last_command_exit_value);
/* Run any traps set on SIGINT, mostly for interactive shells */
- if (signal_is_trapped (SIGINT))
+ if (signal_is_trapped (SIGINT) && signal_is_pending (SIGINT))
run_interrupt_trap (1);
/* Clean up string parser environment. */
diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST
index c8bef8d..0b06381 100755
--- a/tests/RUN-ONE-TEST
+++ b/tests/RUN-ONE-TEST
@@ -1,4 +1,4 @@
-BUILD_DIR=/usr/local/build/bash/bash-current
+BUILD_DIR=/usr/local/build/chet/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
diff --git a/trap.c b/trap.c
index 6db920a..c568718 100644
--- a/trap.c
+++ b/trap.c
@@ -1205,6 +1205,8 @@ run_interrupt_trap (will_throw)
{
if (will_throw && running_trap > 0)
run_trap_cleanup (running_trap - 1);
+ pending_traps[SIGINT] = 0; /* run_pending_traps does this */
+ catch_flag = 0;
_run_trap_internal (SIGINT, "interrupt trap");
}