From 94206228199d6bdf7ba4140f10918641b484523e Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Thu, 2 Jan 2020 10:27:49 -0500 Subject: [PATCH] commit bash-20191219 snapshot --- CWRU/CWRU.chlog | 47 +++++++++++++++++++++++++++ doc/bash.1 | 2 +- doc/bashref.texi | 4 +-- externs.h | 3 +- include/posixstat.h | 22 ++++++++++++- lib/readline/bind.c | 2 +- lib/readline/display.c | 1 + lib/readline/funmap.c | 6 ++-- lib/readline/signals.c | 4 +++ lib/sh/input_avail.c | 73 ++++++++++++++++++++++++++++++++++++++++-- lib/sh/stringlist.c | 4 +-- lib/sh/stringvec.c | 30 +++++++++++++++-- pathexp.c | 4 +-- sig.c | 5 ++- 14 files changed, 188 insertions(+), 19 deletions(-) diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 57271429..90451e4f 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -7040,3 +7040,50 @@ builtins/bind.def sequences that was bound to execute a shell command. We unbind any key sequences from the list before the call to rl_parse_and_bind that don't appear in the list after the call using unbind_unix_command + + 12/19 + ----- +include/posixstat.h + - added some definitions for MinGW. Report and patch from + Eli Zaretskii + + 12/20 + ----- +lib/readline/display.c + - update_line: when wrapping lines containing multibyte characters at + the wrap point, and the number of screen positions consumed by the + first character on the new line isn't the same as the old line, + make sure we set OE before the `goto dumb_update;' since clearing + the rest of the line may use it. Tentative fix for bug reported by + Kirill Chibisov + +lib/readline/signals.c + - _rl_signal_handler: set RL_STATE_SIGHANDLER around SIGWINCH code, + like _rl_handle_signal does + + 12/26 + ----- +lib/sh/stringvec.c + - strvec_posixcmp: new function that conforms to posix requirement for + sorting globs: perform a bytewise comparison if the two strings + collate equally. Posix interp 963 and 1070 + - strvec_sort: take a new flags argument, if non-zero use the posix + string comparison function + +pathexp.c + - shell_glob_filename: call strvec_sort with the flag value to be + posix conformant + +lib/sh/stringlist.c + - strvec_sort: change callers + + 12/29 + ----- +sig.c + - throw_to_top_level: set running_trap to 0 after calling run_trap_cleanup. + This avoids spurious (in non-release versions) warnings from + run_pending_traps the next time a trap handler for that signal + runs. Bug report from Martijn Dekker + + + diff --git a/doc/bash.1 b/doc/bash.1 index 59359b22..c5ae9cf6 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -10784,7 +10784,7 @@ attribute, \fIname\fP will be unset rather than the variable it references. \fB\-n\fP has no effect if the \fB\-f\fP option is supplied. If no options are supplied, each \fIname\fP refers to a variable; if -there is no variable by that name, any function with that name is +there is no variable by that name, a function with that name, if any, is unset. Each unset variable or function is removed from the environment passed to subsequent commands. diff --git a/doc/bashref.texi b/doc/bashref.texi index 8afce4b0..0ebaf110 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -3952,7 +3952,7 @@ the @var{nameref} attribute, @var{name} will be unset rather than the variable it references. @option{-n} has no effect if the @option{-f} option is supplied. If no options are supplied, each @var{name} refers to a variable; if -there is no variable by that name, any function with that name is +there is no variable by that name, a function with that name, if any, is unset. Readonly variables and functions may not be unset. Some shell variables lose their special behavior if they are unset; such @@ -4600,7 +4600,7 @@ from regular files. If @code{read} times out, @code{read} saves any partial input read into the specified variable @var{name}. If @var{timeout} is 0, @code{read} returns immediately, without trying to -read and data. The exit status is 0 if input is available on +read any data. The exit status is 0 if input is available on the specified file descriptor, non-zero otherwise. The exit status is greater than 128 if the timeout is exceeded. diff --git a/externs.h b/externs.h index 1f6b2fd9..d9f89fff 100644 --- a/externs.h +++ b/externs.h @@ -405,8 +405,9 @@ extern int strvec_remove __P((char **, char *)); extern int strvec_len __P((char **)); extern int strvec_search __P((char **, char *)); extern char **strvec_copy __P((char **)); +extern int strvec_posixcmp __P((char **, char **)); extern int strvec_strcmp __P((char **, char **)); -extern void strvec_sort __P((char **)); +extern void strvec_sort __P((char **, int)); extern char **strvec_from_word_list __P((WORD_LIST *, int, int, int *)); extern WORD_LIST *strvec_to_word_list __P((char **, int, int)); diff --git a/include/posixstat.h b/include/posixstat.h index 3eb7f290..b6077860 100644 --- a/include/posixstat.h +++ b/include/posixstat.h @@ -1,7 +1,7 @@ /* posixstat.h -- Posix stat(2) definitions for systems that don't have them. */ -/* Copyright (C) 1987,1991 Free Software Foundation, Inc. +/* Copyright (C) 1987-2019 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -132,6 +132,26 @@ # define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) # define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) # define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +#else /* !S_IRWXU */ + /* S_IRWXU is defined, but "group" and "other" bits might not be + (happens in certain versions of MinGW). */ +# if !defined (S_IRGRP) +# define S_IRGRP (S_IREAD >> 3) /* read, group */ +# define S_IWGRP (S_IWRITE >> 3) /* write, group */ +# define S_IXGRP (S_IEXEC >> 3) /* execute, group */ +# endif /* !S_IRGRP */ + +# if !defined (S_IROTH) +# define S_IROTH (S_IREAD >> 6) /* read, other */ +# define S_IWOTH (S_IWRITE >> 6) /* write, other */ +# define S_IXOTH (S_IEXEC >> 6) /* execute, other */ +# endif /* !S_IROTH */ +# if !defined (S_IRWXG) +# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) +# endif +# if !defined (S_IRWXO) +# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +# endif #endif /* !S_IRWXU */ /* These are non-standard, but are used in builtins.c$symbolic_umask() */ diff --git a/lib/readline/bind.c b/lib/readline/bind.c index b6970df6..f25db5c1 100644 --- a/lib/readline/bind.c +++ b/lib/readline/bind.c @@ -788,7 +788,7 @@ _rl_untranslate_macro_value (char *seq, int use_escapes) /* Return a pointer to the function that STRING represents. If STRING doesn't have a matching function, then a NULL pointer - is returned. */ + is returned. The string match is case-insensitive. */ rl_command_func_t * rl_named_function (const char *string) { diff --git a/lib/readline/display.c b/lib/readline/display.c index 66c09192..4631047b 100644 --- a/lib/readline/display.c +++ b/lib/readline/display.c @@ -1666,6 +1666,7 @@ update_line (char *old, char *new, int current_line, int omax, int nmax, int inv and do a dumb update. */ if (newwidth != oldwidth) { + oe = old + omax; ne = new + nmax; nd = newbytes; nfd = new + nd; diff --git a/lib/readline/funmap.c b/lib/readline/funmap.c index aaf144de..3b836720 100644 --- a/lib/readline/funmap.c +++ b/lib/readline/funmap.c @@ -157,7 +157,7 @@ static const FUNMAP default_funmap[] = { { "vi-backward-bigword", rl_vi_bWord }, { "vi-backward-word", rl_vi_bword }, { "vi-bWord", rl_vi_bWord }, - { "vi-bword", rl_vi_bword }, + { "vi-bword", rl_vi_bword }, /* BEWARE: name matching is case insensitive */ { "vi-change-case", rl_vi_change_case }, { "vi-change-char", rl_vi_change_char }, { "vi-change-to", rl_vi_change_to }, @@ -171,13 +171,13 @@ static const FUNMAP default_funmap[] = { { "vi-end-bigword", rl_vi_eWord }, { "vi-end-word", rl_vi_end_word }, { "vi-eof-maybe", rl_vi_eof_maybe }, - { "vi-eword", rl_vi_eword }, + { "vi-eword", rl_vi_eword }, /* BEWARE: name matching is case insensitive */ { "vi-fWord", rl_vi_fWord }, { "vi-fetch-history", rl_vi_fetch_history }, { "vi-first-print", rl_vi_first_print }, { "vi-forward-bigword", rl_vi_fWord }, { "vi-forward-word", rl_vi_fword }, - { "vi-fword", rl_vi_fword }, + { "vi-fword", rl_vi_fword }, /* BEWARE: name matching is case insensitive */ { "vi-goto-mark", rl_vi_goto_mark }, { "vi-insert-beg", rl_vi_insert_beg }, { "vi-insertion-mode", rl_vi_insert_mode }, diff --git a/lib/readline/signals.c b/lib/readline/signals.c index 074de6ad..055de2ee 100644 --- a/lib/readline/signals.c +++ b/lib/readline/signals.c @@ -144,6 +144,8 @@ _rl_signal_handler (int sig) #if defined (SIGWINCH) if (sig == SIGWINCH) { + RL_SETSTATE(RL_STATE_SIGHANDLER); + rl_resize_terminal (); /* XXX - experimental for now */ /* Call a signal hook because though we called the original signal handler @@ -151,6 +153,8 @@ _rl_signal_handler (int sig) ourselves. */ if (rl_signal_event_hook) (*rl_signal_event_hook) (); + + RL_UNSETSTATE(RL_STATE_SIGHANDLER); } else #endif diff --git a/lib/sh/input_avail.c b/lib/sh/input_avail.c index ac157a9f..695165fd 100644 --- a/lib/sh/input_avail.c +++ b/lib/sh/input_avail.c @@ -1,7 +1,7 @@ /* input_avail.c -- check whether or not data is available for reading on a specified file descriptor. */ -/* Copyright (C) 2008,2009 Free Software Foundation, Inc. +/* Copyright (C) 2008,2009-2019 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -33,6 +33,10 @@ # include #endif /* HAVE_SYS_FILE_H */ +#if defined (HAVE_PSELECT) +# include +#endif + #if defined (HAVE_UNISTD_H) # include #endif /* HAVE_UNISTD_H */ @@ -82,10 +86,8 @@ input_avail (fd) timeout.tv_usec = 0; result = select (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout); return ((result <= 0) ? 0 : 1); - #endif - result = -1; #if defined (FIONREAD) errno = 0; result = ioctl (fd, FIONREAD, &chars_avail); @@ -96,3 +98,68 @@ input_avail (fd) return 0; } + +/* Wait until NCHARS are available for reading on file descriptor FD. + This can wait indefinitely. Return -1 on error. */ +int +nchars_avail (fd, nchars) + int fd; + int nchars; +{ + int result, chars_avail; +#if defined(HAVE_SELECT) + fd_set readfds, exceptfds; +#endif +#if defined (HAVE_PSELECT) + sigset_t set, oset; +#endif + + if (fd < 0 || nchars < 0) + return -1; + if (nchars == 0) + return (input_avail (fd)); + + chars_avail = 0; + +#if defined (HAVE_SELECT) + FD_ZERO (&readfds); + FD_ZERO (&exceptfds); + FD_SET (fd, &readfds); + FD_SET (fd, &exceptfds); +#endif +#if defined (HAVE_SELECT) || defined (HAVE_PSELECT) + sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set); +# ifdef SIGCHLD + sigaddset (&set, SIGCHLD); +# endif + sigemptyset (&oset); +#endif + + while (1) + { + result = 0; +#if defined (HAVE_PSELECT) + /* XXX - use pselect(2) to block SIGCHLD atomically */ + result = pselect (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, (struct timespec *)NULL, &set); +#elif defined (HAVE_SELECT) + sigprocmask (SIG_BLOCK, &set, &oset); + result = select (fd + 1, &readfds, (fd_set *)NULL, &exceptfds, (struct timeval *)NULL); + sigprocmask (SIG_BLOCK, &oset, (sigset_t *)NULL); +#endif + if (result < 0) + return -1; + +#if defined (FIONREAD) + errno = 0; + result = ioctl (fd, FIONREAD, &chars_avail); + if (result == -1 && errno == EIO) + return -1; + if (chars_avail >= nchars) + break; +#else + break; +#endif + } + + return 0; +} diff --git a/lib/sh/stringlist.c b/lib/sh/stringlist.c index b0c272ae..3f28b631 100644 --- a/lib/sh/stringlist.c +++ b/lib/sh/stringlist.c @@ -1,6 +1,6 @@ /* stringlist.c - functions to handle a generic `list of strings' structure */ -/* Copyright (C) 2000-2002 Free Software Foundation, Inc. +/* Copyright (C) 2000-2019 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -255,7 +255,7 @@ strlist_sort (sl) { if (sl == 0 || sl->list_len == 0 || sl->list == 0) return; - strvec_sort (sl->list); + strvec_sort (sl->list, 0); } STRINGLIST * diff --git a/lib/sh/stringvec.c b/lib/sh/stringvec.c index c7ac3e9b..86000429 100644 --- a/lib/sh/stringvec.c +++ b/lib/sh/stringvec.c @@ -156,6 +156,28 @@ strvec_copy (array) return (ret); } +/* Comparison routine for use by qsort that conforms to the new Posix + requirements (http://austingroupbugs.net/view.php?id=1070). + + Perform a bytewise comparison if *S1 and *S2 collate equally. */ +int +strvec_posixcmp (s1, s2) + register char **s1, **s2; +{ + int result; + +#if defined (HAVE_STRCOLL) + result = strcoll (*s1, *s2); + if (result != 0) + return result; +#endif + + if ((result = **s1 - **s2) == 0) + result = strcmp (*s1, *s2); + + return (result); +} + /* Comparison routine for use with qsort() on arrays of strings. Uses strcoll(3) if available, otherwise it uses strcmp(3). */ int @@ -176,10 +198,14 @@ strvec_strcmp (s1, s2) /* Sort ARRAY, a null terminated array of pointers to strings. */ void -strvec_sort (array) +strvec_sort (array, posix) char **array; + int posix; { - qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_strcmp); + if (posix) + qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_posixcmp); + else + qsort (array, strvec_len (array), sizeof (char *), (QSFUNC *)strvec_strcmp); } /* Cons up a new array of words. The words are taken from LIST, diff --git a/pathexp.c b/pathexp.c index c6825736..95590029 100644 --- a/pathexp.c +++ b/pathexp.c @@ -448,7 +448,7 @@ shell_glob_filename (pathname, qflags) if (should_ignore_glob_matches ()) ignore_glob_matches (results); if (results && results[0]) - strvec_sort (results); + strvec_sort (results, 1); /* posix sort */ else { FREE (results); @@ -475,7 +475,7 @@ shell_glob_filename (pathname, qflags) if (should_ignore_glob_matches ()) ignore_glob_matches (results); if (results && results[0]) - strvec_sort (results); + strvec_sort (results, 1); /* posix sort */ else { FREE (results); diff --git a/sig.c b/sig.c index d49d0d4f..9e5581f1 100644 --- a/sig.c +++ b/sig.c @@ -416,7 +416,10 @@ throw_to_top_level () parse_and_execute_cleanup (-1); if (running_trap > 0) - run_trap_cleanup (running_trap - 1); + { + run_trap_cleanup (running_trap - 1); + running_trap = 0; + } #if defined (JOB_CONTROL) give_terminal_to (shell_pgrp, 0);