diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 904e2ded..3ab4f7e1 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -13465,3 +13465,62 @@ trap.c them after the action completes. Make sure to handle the case where the trap action runs break or continue. From a report by Dimitrios Christou + + 10/23 + ----- +lib/readline/display.c + - rl_redisplay: update fix from 5/19 to use _rl_last_c_pos in a single + byte locale and local_prompt_len otherwise + From https://bugs.gentoo.org/984299 via Kerin Millar + + 10/24 + ----- +jobs.c + - kill_pid: if we are killing a process or job in a situation where + we can't use killpg(), make sure to set p to p->next even if we + skip over a job because we think it's already terminated so we go + through all of the processes in the job's pipeline + Report and fix from Edgar MAGDELAINE + + 10/27 + ----- +lib/sh/zread.c + - zfileno: keep track of the file descriptor most recently used for + local buffering in zreadc/zreadcintr/zreadn (everything that uses + lbuf/lused/lind) + - zcheckfd: new function, return true if the file descriptor passed as + an argument is the same as zfileno and with presumably buffered + data + - zreset: new function, break code that resets lused/lind/etc into + separate function, change callers + - zpurge: new function, reset any buffered or pushed input and unset + zfileno + +externs.h + - zcheckfd, zpurge: new extern declarations + +lib/readline/histexpand.c + - postproc_subst_rhs: use size_t for i, j, new_size + Report from Osvaldo J. Filho + +lib/readline/bind.c, +lib/readline/complete.c +lib/readline/display.c, +lib/readline/histexpand.c, +lib/readline/isearch.c, +lib/readline/kill.c, +lib/readline/macro.c, +lib/readline/util.c, +lib/readline/rlprivate.h + - make sure places and variables that maintain buffer or struct sizes + or count struct or buffer elements are size_t + + 10/30 + ----- +redir.c + - do_redirection_internal: in contexts where a file descriptor that + was the target of a redirection will be closed, check whether + that file descriptor was the last one used to read buffered input + with zreadc/zreadcintr/zreadn and invalidate the buffered data + if so + Report from Edgar MAGDELAINE diff --git a/builtins/getopt.c b/builtins/getopt.c index 9ad08594..fce2d72f 100644 --- a/builtins/getopt.c +++ b/builtins/getopt.c @@ -1,4 +1,4 @@ -/* getopt.c - getopt for Bash. Used by the getopt builtin. */ +/* getopt.c - getopt for Bash. Used by the getopts builtin. */ /* Copyright (C) 1993-2009,2022,2026 Free Software Foundation, Inc. @@ -252,6 +252,7 @@ sh_getopt_save_istate (void) ret->gs_curopt = sh_curopt; ret->gs_nextchar = nextchar; /* XXX */ ret->gs_charindex = sh_charindex; + ret->gs_vcontext = variable_context; /* informational only */ ret->gs_flags = 0; /* XXX for later use */ return ret; diff --git a/builtins/getopt.h b/builtins/getopt.h index 0faa3328..fd723460 100644 --- a/builtins/getopt.h +++ b/builtins/getopt.h @@ -68,6 +68,7 @@ typedef struct sh_getopt_state int gs_curopt; char *gs_nextchar; int gs_charindex; + int gs_vcontext; int gs_flags; } sh_getopt_state_t; diff --git a/externs.h b/externs.h index 68c1aab1..d914a786 100644 --- a/externs.h +++ b/externs.h @@ -572,6 +572,8 @@ extern ssize_t zreadn (int, char *, size_t); extern int zungetc (int); extern void zreset (void); extern void zsyncfd (int); +extern int zcheckfd (int); +extern void zpurge (int); /* declarations for functions defined in lib/sh/zwrite.c */ extern int zwrite (int, char *, size_t); diff --git a/jobs.c b/jobs.c index 54d64964..b28ab0cf 100644 --- a/jobs.c +++ b/jobs.c @@ -3999,11 +3999,14 @@ kill_pid (pid_t pid, int sig, int group) p = jobs[job]->pipe; do { - if (PALIVE (p) == 0) - continue; /* avoid pid recycling problem */ - kill (p->pid, sig); - if (PEXITED (p) && (sig == SIGTERM || sig == SIGHUP)) - kill (p->pid, SIGCONT); + /* Don't bother killing processes we think have already + terminated, in case the pid has already been reused. */ + if (PALIVE (p)) + { + kill (p->pid, sig); + if (PEXITED (p) && (sig == SIGTERM || sig == SIGHUP)) + kill (p->pid, SIGCONT); + } p = p->next; } while (p != jobs[job]->pipe); diff --git a/lib/readline/bind.c b/lib/readline/bind.c index c663b63c..e55cbde9 100644 --- a/lib/readline/bind.c +++ b/lib/readline/bind.c @@ -1,6 +1,6 @@ /* bind.c -- key binding and startup file support for the readline library. */ -/* Copyright (C) 1987-2024 Free Software Foundation, Inc. +/* Copyright (C) 1987-2026 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -1231,7 +1231,7 @@ const char *rl_readline_name = "other"; /* Stack of previous values of parsing_conditionalized_out. */ static unsigned char *if_stack = (unsigned char *)NULL; -static int if_stack_depth; +static size_t if_stack_depth; static size_t if_stack_size; /* Push _rl_parsing_conditionalized_out, and set parser state based @@ -1444,7 +1444,7 @@ parser_if (char *args) static int parser_else (char *args) { - register int i; + size_t i; if (if_stack_depth == 0) { @@ -2463,7 +2463,8 @@ rl_get_keymap_name (Keymap map) int rl_set_keymap_name (const char *name, Keymap map) { - int i, ni, mi; + int ni, mi; + size_t i; /* First check whether or not we're trying to rename a builtin keymap */ mi = _rl_get_keymap_by_map (map); diff --git a/lib/readline/complete.c b/lib/readline/complete.c index 74e1b601..0bb569b2 100644 --- a/lib/readline/complete.c +++ b/lib/readline/complete.c @@ -1,6 +1,6 @@ /* complete.c -- filename completion for readline. */ -/* Copyright (C) 1987-2025 Free Software Foundation, Inc. +/* Copyright (C) 1987-2026 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -1006,7 +1006,8 @@ fnprint (const char *to_print, int prefix_bytes, const char *real_pathname) static int print_filename (char *to_print, char *full_pathname, int prefix_bytes) { - int printed_len, extension_char, slen, tlen; + int printed_len, extension_char; + size_t slen, tlen; char *s, c, *new_full_pathname, *dn; extension_char = 0; @@ -1329,7 +1330,8 @@ static char ** remove_duplicate_matches (char **matches) { char *lowest_common; - int i, j, newlen; + int i, j; + size_t newlen; char dead_slot; char **temp_array; @@ -1473,7 +1475,7 @@ compute_lcd_of_matches (char **match_list, int matches, const char *text) } else { - match_list[0] = (char *)xmalloc (low + 1); + match_list[0] = (char *)xmalloc ((size_t)low + 1); /* XXX - this might need changes in the presence of multibyte chars */ diff --git a/lib/readline/display.c b/lib/readline/display.c index 2c3cc752..16104e92 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -225,7 +225,7 @@ static int last_lmargin; /* A buffer for `modeline' messages. */ static char *msg_buf = 0; -static int msg_bufsiz = 0; +static size_t msg_bufsiz = 0; /* Non-zero forces the redisplay even if we thought it was unnecessary. */ static int forced_display; @@ -357,7 +357,8 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp) { char *r, *ret, *p, *igstart, *nprompt, *ms; int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars; - int mlen, newlines, newlines_guess, bound, can_add_invis, lastinvis; + int mlen, newlines, bound, can_add_invis, lastinvis; + size_t newlines_guess; int mb_cur_max; /* We only expand the mode string for the last line of a multiline prompt @@ -365,8 +366,10 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp) ms = (((pmt == rl_prompt) ^ (flags & PMT_MULTILINE)) && _rl_show_mode_in_prompt) ? prompt_modestr (&mlen) : 0; if (ms) { - l = strlen (pmt); - nprompt = (char *)xmalloc (l + mlen + 1); + size_t newlen; + + newlen = strlen (pmt) + mlen + 1; + nprompt = (char *)xmalloc (newlen); memcpy (nprompt, ms, mlen); strcpy (nprompt + mlen, pmt); } @@ -1510,9 +1513,11 @@ rl_redisplay (void) /* cursor_bufpos is where the portion of the prompt that appears on the current screen line begins in the buffer. It is a buffer position, an index into curline - (local_prompt + pmt_offset) */ - cursor_bufpos = pmt_offset + local_prompt_len; - + (local_prompt + pmt_offset in multibyte mode, single-byte + locales use _rl_last_c_pos) */ + cursor_bufpos = pmt_offset + + (mb_cur_max == 1 || rl_byte_oriented) ? _rl_last_c_pos : local_prompt_len; + if (local_prompt && local_prompt_invis_chars[cursor_linenum] && _rl_last_c_pos > 0 && cursor_bufpos <= prompt_last_invisible) @@ -3265,7 +3270,7 @@ rl_restore_prompt (void) char * _rl_make_prompt_for_search (int pchar) { - int len; + size_t len; char *pmt, *p; rl_save_prompt (); diff --git a/lib/readline/funmap.c b/lib/readline/funmap.c index b5773ce6..aba13537 100644 --- a/lib/readline/funmap.c +++ b/lib/readline/funmap.c @@ -1,6 +1,6 @@ /* funmap.c -- attach names to functions. */ -/* Copyright (C) 1987-2024 Free Software Foundation, Inc. +/* Copyright (C) 1987-2026 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. diff --git a/lib/readline/histexpand.c b/lib/readline/histexpand.c index c8e67415..fd500c3e 100644 --- a/lib/readline/histexpand.c +++ b/lib/readline/histexpand.c @@ -1,6 +1,6 @@ /* histexpand.c -- history expansion. */ -/* Copyright (C) 1989-2021,2023-2025 Free Software Foundation, Inc. +/* Copyright (C) 1989-2021,2023-2026 Free Software Foundation, Inc. This file contains the GNU History Library (History), a set of routines for managing the text of previously typed lines. @@ -337,7 +337,7 @@ quote_breaks (char *s) { register char *p, *r; char *ret; - int len = 3; + size_t len = 3; for (p = s; p && *p; p++, len++) { @@ -378,7 +378,7 @@ hist_error(const char *s, int start, int current, int errtype) { char *temp; const char *emsg; - int ll, elen; + size_t ll, elen; ll = current - start; @@ -436,7 +436,7 @@ hist_error(const char *s, int start, int current, int errtype) static char * get_subst_pattern (const char *str, int *iptr, int delimiter, int is_rhs, int *lenptr) { - register int si, i, j, k; + size_t si, i, j, k; char *s; #if defined (HANDLE_MULTIBYTE) mbstate_t ps; @@ -492,7 +492,7 @@ static void postproc_subst_rhs (void) { char *new; - int i, j, new_size; + size_t i, j, new_size; new = (char *)xmalloc (new_size = subst_rhs_len + subst_lhs_len); for (i = j = 0; i < subst_rhs_len; i++) @@ -529,10 +529,10 @@ postproc_subst_rhs (void) static int history_expand_internal (const char *string, int start, int qc, int *end_index_ptr, char **ret_string, char *current_line) { - int i, n, starting_index; + int i, starting_index; int substitute_globally, subst_bywords, want_quotes, print_only; char *event, *temp, *result, *tstr, *t, c, *word_spec; - size_t result_len; + size_t n, result_len; #if defined (HANDLE_MULTIBYTE) mbstate_t ps; @@ -783,7 +783,7 @@ history_expand_internal (const char *string, int start, int qc, int *end_index_p if (STREQN (temp+si, subst_lhs, subst_lhs_len)) { - int len = subst_rhs_len - subst_lhs_len + l_temp; + size_t len = subst_rhs_len - subst_lhs_len + l_temp; new_event = (char *)xmalloc (1 + len); strncpy (new_event, temp, si); strncpy (new_event + si, subst_rhs, subst_rhs_len); @@ -1170,7 +1170,8 @@ history_expand (const char *hstring, char **output) } else if (dquote == 0 && history_quotes_inhibit_expansion) { - int quote, slen; + int quote; + size_t slen; flag = (i > 0 && string[i - 1] == '$'); quote = i++; @@ -1620,8 +1621,8 @@ get_word: static char * history_substring (const char *string, int start, int end) { - register int len; - register char *result; + size_t len; + char *result; len = end - start; result = (char *)xmalloc (len + 1); diff --git a/lib/readline/histfile.c b/lib/readline/histfile.c index 9e39488c..5e46fcb0 100644 --- a/lib/readline/histfile.c +++ b/lib/readline/histfile.c @@ -1,6 +1,6 @@ /* histfile.c - functions to manipulate the history file. */ -/* Copyright (C) 1989-2019,2023-2025 Free Software Foundation, Inc. +/* Copyright (C) 1989-2019,2023-2026 Free Software Foundation, Inc. This file contains the GNU History Library (History), a set of routines for managing the text of previously typed lines. diff --git a/lib/readline/isearch.c b/lib/readline/isearch.c index e2125e46..96f47bdf 100644 --- a/lib/readline/isearch.c +++ b/lib/readline/isearch.c @@ -6,7 +6,7 @@ /* */ /* **************************************************************** */ -/* Copyright (C) 1987-2021,2023,2025 Free Software Foundation, Inc. +/* Copyright (C) 1987-2026 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -72,7 +72,7 @@ static void _rl_isearch_fini (_rl_search_cxt *); /* Last search string and its length. */ static char *last_isearch_string; -static int last_isearch_string_len; +static size_t last_isearch_string_len; static char * const default_isearch_terminators = "\033\012"; diff --git a/lib/readline/kill.c b/lib/readline/kill.c index 9d3bdb48..bcb5751b 100644 --- a/lib/readline/kill.c +++ b/lib/readline/kill.c @@ -1,6 +1,6 @@ /* kill.c -- kill ring management. */ -/* Copyright (C) 1994-2025 Free Software Foundation, Inc. +/* Copyright (C) 1994-2026 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -91,7 +91,7 @@ static int _rl_copy_to_kill_ring (char *text, int append) { char *old, *new; - int slot; + size_t slot; /* First, find the slot to work with. */ if (_rl_last_command_was_kill == 0 || rl_kill_ring == 0) @@ -111,7 +111,7 @@ _rl_copy_to_kill_ring (char *text, int append) slot = rl_kill_ring_length; if (slot == rl_max_kills) { - register int i; + int i; xfree (rl_kill_ring[0]); for (i = 0; i < slot; i++) rl_kill_ring[i] = rl_kill_ring[i + 1]; diff --git a/lib/readline/macro.c b/lib/readline/macro.c index 9f26f4b7..0c8073eb 100644 --- a/lib/readline/macro.c +++ b/lib/readline/macro.c @@ -1,6 +1,6 @@ /* macro.c -- keyboard macros for readline. */ -/* Copyright (C) 1994-2009,2017 Free Software Foundation, Inc. +/* Copyright (C) 1994-2009,2017,2026 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -62,7 +62,7 @@ char *rl_executing_macro = (char *)NULL; /* The offset in the above string to the next character to be read. */ -static int executing_macro_index; +static size_t executing_macro_index; /* The current macro string being built. Characters get stuffed in here by add_macro_char (). */ @@ -72,7 +72,7 @@ static char *current_macro = (char *)NULL; static size_t current_macro_size; /* The index at which characters are being added to current_macro. */ -static int current_macro_index; +static size_t current_macro_index; /* A structure used to save nested macro strings. It is a linked list of string/index for each saved macro. */ diff --git a/lib/readline/rlprivate.h b/lib/readline/rlprivate.h index c8cb6736..320236b1 100644 --- a/lib/readline/rlprivate.h +++ b/lib/readline/rlprivate.h @@ -1,7 +1,7 @@ /* rlprivate.h -- functions and variables global to the readline library, but not intended for use by applications. */ -/* Copyright (C) 1999-2025 Free Software Foundation, Inc. +/* Copyright (C) 1999-2026 Free Software Foundation, Inc. This file is part of the GNU Readline Library (Readline), a library for reading lines of text with interactive input and history editing. @@ -75,8 +75,8 @@ typedef struct __rl_search_context int sflags; char *search_string; - int search_string_index; - int search_string_size; + size_t search_string_index; + size_t search_string_size; char **lines; char *allocated_line; diff --git a/lib/readline/text.c b/lib/readline/text.c index 72baf331..87c53d54 100644 --- a/lib/readline/text.c +++ b/lib/readline/text.c @@ -717,7 +717,7 @@ _rl_insert_char (int count, int c) register int i; char *string; #ifdef HANDLE_MULTIBYTE - int string_size; + size_t string_size; char incoming[MB_LEN_MAX + 1]; int incoming_length = 0; mbstate_t ps_back; diff --git a/lib/readline/util.c b/lib/readline/util.c index c8c23de5..2b57fb95 100644 --- a/lib/readline/util.c +++ b/lib/readline/util.c @@ -147,7 +147,7 @@ rl_tty_status (int count, int key) char * rl_copy_text (int from, int to) { - register int length; + size_t length; char *copy; /* Fix it if the caller is confused. */ @@ -180,9 +180,9 @@ rl_extend_line_buffer (int len) int rl_tilde_expand (int ignore, int key) { - register int start, end; + int start, end; char *homedir, *temp; - int len; + size_t len; end = rl_point; start = end - 1; diff --git a/lib/sh/zread.c b/lib/sh/zread.c index a1862165..3c1aa2f8 100644 --- a/lib/sh/zread.c +++ b/lib/sh/zread.c @@ -200,6 +200,7 @@ zreadintr (int fd, char *buf, size_t len) static char lbuf[ZBUFSIZ]; static size_t lind, lused; +static int zfileno = -1; /* fd associated with latest read into lbuf */ ssize_t zreadc (int fd, char *cp) @@ -223,6 +224,7 @@ zreadc (int fd, char *cp) return nr; } lused = nr; + zfileno = fd; } if (cp) *cp = lbuf[lind++]; @@ -253,6 +255,7 @@ zreadcintr (int fd, char *cp) return nr; } lused = nr; + zfileno = fd; } if (cp) *cp = lbuf[lind++]; @@ -285,6 +288,7 @@ zreadn (int fd, char *cp, size_t len) return nr; } lused = nr; + zfileno = fd; } if (cp) *cp = lbuf[lind++]; @@ -331,8 +335,23 @@ zsyncfd (int fd) r = lseek (fd, -off, SEEK_CUR); if (r != -1) - { - lused = lind = 0; - zpushind = zpopind = 0; - } + zreset (); +} + +/* Return true if FD is the same as ZFILENO, the file descriptor associated + with the most recent call to one of the read functions above that populates + LBUF */ +int +zcheckfd (int fd) +{ + return (zfileno >= 0 && fd == zfileno); +} + +/* Throw away buffered data associated with FD. The caller should have already + made sure that FD == ZFILENO by calling zcheckfd() */ +void +zpurge (int fd) +{ + zreset (); + zfileno = -1; } diff --git a/redir.c b/redir.c index 353fa013..efd2c644 100644 --- a/redir.c +++ b/redir.c @@ -1051,6 +1051,10 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp) if (ri == r_input_direction || ri == r_input_output) duplicate_buffered_stream (fd, redirector); + if (ri == r_input_direction || ri == r_input_output) + if (zcheckfd (redirector)) + zpurge (redirector); + /* * If we're remembering, then this is the result of a while, for * or until loop with a loop redirection, or a function/builtin @@ -1221,6 +1225,10 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp) if (ri == r_duplicating_input || ri == r_move_input) duplicate_buffered_stream (redir_fd, redirector); + if (ri == r_duplicating_input || ri == r_move_input) + if (zcheckfd (redirector)) + zpurge (redirector); + /* First duplicate the close-on-exec state of redirectee. dup2 leaves the flag unset on the new descriptor, which means it stays open. Only set the close-on-exec bit for file descriptors @@ -1257,6 +1265,8 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp) #if defined (COPROCESS_SUPPORT) coproc_fdchk (redir_fd); /* XXX - loses coproc fds */ #endif + if (zcheckfd (redir_fd)) + zpurge (redir_fd); } } break; @@ -1291,6 +1301,9 @@ do_redirection_internal (REDIRECT *redirect, int flags, char **fnp) check_bash_input (redirector); r = close_buffered_fd (redirector); + if (zcheckfd (redirector)) + zpurge (redirector); + if (r < 0 && (rflags & RX_INTERNAL) && (errno == EIO || errno == ENOSPC)) REDIRECTION_ERROR (r, errno, -1); }