commit bash-20200406 snapshot

This commit is contained in:
Chet Ramey
2020-04-08 17:09:56 -04:00
parent e34adc2c3b
commit ea31c00845
11 changed files with 266 additions and 101 deletions
+59
View File
@@ -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
+21
View File
@@ -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;
}
-7
View File
@@ -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. */
+23 -17
View File
@@ -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;
/* XXX - block SIGTERM here and unblock in child after fork resets the
set of pending signals? */
sigemptyset (&oset_copy);
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &oset_copy);
sigaddset (&oset_copy, SIGTERM);
/* 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);
}
+139 -65
View File
@@ -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)
+1 -1
View File
@@ -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)
{
+1 -1
View File
@@ -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 */
/* **************************************************************** */
/* */
+16 -5
View File
@@ -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)
{
+3 -4
View File
@@ -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. */
+1 -1
View File
@@ -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
+2
View File
@@ -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");
}