diff options
| author | Chet Ramey <chet.ramey@case.edu> | 2020-04-08 17:09:56 -0400 |
|---|---|---|
| committer | Chet Ramey <chet.ramey@case.edu> | 2020-04-08 17:09:56 -0400 |
| commit | ea31c00845c858098d232bd014bf27b5a63a668b (patch) | |
| tree | 20debaadb45cae9571cca0aa0b8fd62d44575c68 | |
| parent | e34adc2c3b6b8722d0316f3b26fe5346faf94dea (diff) | |
| download | bash-ea31c00845c858098d232bd014bf27b5a63a668b.tar.gz | |
commit bash-20200406 snapshot
| -rw-r--r-- | CWRU/CWRU.chlog | 59 | ||||
| -rw-r--r-- | bashline.c | 21 | ||||
| -rw-r--r-- | execute_cmd.c | 7 | ||||
| -rw-r--r-- | jobs.c | 40 | ||||
| -rw-r--r-- | lib/readline/display.c | 204 | ||||
| -rw-r--r-- | lib/readline/kill.c | 2 | ||||
| -rw-r--r-- | lib/readline/readline.c | 2 | ||||
| -rw-r--r-- | nojobs.c | 21 | ||||
| -rw-r--r-- | sig.c | 7 | ||||
| -rwxr-xr-x | tests/RUN-ONE-TEST | 2 | ||||
| -rw-r--r-- | trap.c | 2 |
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 @@ -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. */ @@ -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 */ /* **************************************************************** */ /* */ @@ -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) { @@ -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 @@ -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"); } |
