fixes for bracket expressions in pathname expansion; changes for select/pselect; jobs builtin now removes terminated jobs from the jobs table after notifying

This commit is contained in:
Chet Ramey
2022-11-18 11:01:00 -05:00
parent 96115811d8
commit 407d9afca0
12 changed files with 153 additions and 32 deletions
+46 -9
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 1991-2021 Free Software Foundation, Inc.
/* Copyright (C) 1991-2022 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -343,6 +343,11 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
(n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/'))))
return (FNM_NOMATCH);
/* If we are matching pathnames, we can't match a slash with a
bracket expression. */
if (sc == L('/') && (flags & FNM_PATHNAME))
return (FNM_NOMATCH);
/* `?' cannot match `.' or `..' if it is the first character of the
string or if it is the first character following a slash and
we are matching a pathname. */
@@ -403,6 +408,8 @@ PARSE_COLLSYM (p, vp)
return (p + pc + 2);
}
#define SLASH_PATHNAME(c) (c == L('/') && (flags & FNM_PATHNAME))
/* Use prototype definition here because of type promotion. */
static CHAR *
#if defined (PROTOTYPES)
@@ -451,6 +458,12 @@ BRACKMATCH (p, test, flags)
{
pc = FOLD (p[1]);
p += 4;
/* Finding a slash in a bracket expression means you have to
match the bracket as an ordinary character (see below). */
if (pc == L('/') && (flags & FNM_PATHNAME))
return ((test == L('[')) ? savep : (CHAR *)0); /*]*/
if (COLLEQUIV (test, pc))
{
/*[*/ /* Move past the closing `]', since the first thing we do at
@@ -463,6 +476,10 @@ BRACKMATCH (p, test, flags)
c = *p++;
if (c == L('\0'))
return ((test == L('[')) ? savep : (CHAR *)0); /*]*/
else if (c == L('/') && (flags & FNM_PATHNAME))
return ((test == L('[')) ? savep : (CHAR *)0); /*]*/
else if (c == L(']'))
break;
c = FOLD (c);
continue;
}
@@ -475,11 +492,11 @@ BRACKMATCH (p, test, flags)
pc = 0; /* make sure invalid char classes don't match. */
/* Find end of character class name */
for (close = p + 1; *close != '\0'; close++)
for (close = p + 1; *close != '\0' && SLASH_PATHNAME(*close) == 0; close++)
if (*close == L(':') && *(close+1) == L(']'))
break;
if (*close != L('\0'))
if (*close != L('\0') && SLASH_PATHNAME(*close) == 0)
{
ccname = (CHAR *)malloc ((close - p) * sizeof (CHAR));
if (ccname == 0)
@@ -526,6 +543,8 @@ BRACKMATCH (p, test, flags)
c = *p++;
if (c == L('\0'))
return ((test == L('[')) ? savep : (CHAR *)0);
else if (c == L('/') && (flags & FNM_PATHNAME))
return ((test == L('[')) ? savep : (CHAR *)0); /*]*/
else if (c == L(']'))
break;
c = FOLD (c);
@@ -565,15 +584,23 @@ BRACKMATCH (p, test, flags)
if (c == L('\0'))
return ((test == L('[')) ? savep : (CHAR *)0);
/* POSIX.2 2.13.3 says: `If a <slash> character is found following an
unescaped <left-square-bracket> character before a corresponding
<right-square-bracket> is found, the open bracket shall be treated
as an ordinary character.' If we find a slash in a bracket
expression and the flags indicate we're supposed to be treating the
string like a pathname, we have to treat the `[' as just a character
to be matched. */
if (c == L('/') && (flags & FNM_PATHNAME))
return ((test == L('[')) ? savep : (CHAR *)0);
c = *p++;
c = FOLD (c);
if (c == L('\0'))
return ((test == L('[')) ? savep : (CHAR *)0);
if ((flags & FNM_PATHNAME) && c == L('/'))
/* [/] can never match when matching a pathname. */
return (CHAR *)0;
else if (c == L('/') && (flags & FNM_PATHNAME))
return ((test == L('[')) ? savep : (CHAR *)0);
/* This introduces a range, unless the `-' is the last
character of the class. Find the end of the range
@@ -584,7 +611,9 @@ BRACKMATCH (p, test, flags)
if (!(flags & FNM_NOESCAPE) && cend == L('\\'))
cend = *p++;
if (cend == L('\0'))
return (CHAR *)0;
return ((test == L('[')) ? savep : (CHAR *)0);
else if (cend == L('/') && (flags & FNM_PATHNAME))
return ((test == L('[')) ? savep : (CHAR *)0);
if (cend == L('[') && *p == L('.'))
{
p = PARSE_COLLSYM (p, &pc);
@@ -636,6 +665,8 @@ matched:
/* A `[' without a matching `]' is just another character to match. */
if (c == L('\0'))
return ((test == L('[')) ? savep : (CHAR *)0);
else if (c == L('/') && (flags & FNM_PATHNAME))
return ((test == L('[')) ? savep : (CHAR *)0);
oc = c;
c = *p++;
@@ -643,7 +674,10 @@ matched:
{
brcnt++;
brchrp = p++; /* skip over the char after the left bracket */
if ((c = *p) == L('\0'))
c = *p;
if (c == L('\0'))
return ((test == L('[')) ? savep : (CHAR *)0);
else if (c == L('/') && (flags & FNM_PATHNAME))
return ((test == L('[')) ? savep : (CHAR *)0);
/* If *brchrp == ':' we should check that the rest of the characters
form a valid character class name. We don't do that yet, but we
@@ -666,6 +700,9 @@ matched:
{
if (*p == '\0')
return (CHAR *)0;
/* We don't allow backslash to quote slash if we're matching pathnames */
else if (*p == L('/') && (flags & FNM_PATHNAME))
return ((test == L('[')) ? savep : (CHAR *)0);
/* XXX 1003.2d11 is unclear if this is right. */
++p;
}
+2 -4
View File
@@ -616,10 +616,8 @@ rl_expand_prompt (char *prompt)
prompt_visible_length = prompt_physical_chars = 0;
if (local_prompt_invis_chars == 0)
{
local_prompt_invis_chars = (int *)xmalloc (sizeof (int));
local_prompt_invis_chars[0] = 0;
}
local_prompt_invis_chars = (int *)xmalloc (sizeof (int));
local_prompt_invis_chars[0] = 0;
if (prompt == 0 || *prompt == 0)
return (0);
+3 -3
View File
@@ -1,6 +1,6 @@
/* input.c -- character input functions for readline. */
/* Copyright (C) 1994-2021 Free Software Foundation, Inc.
/* Copyright (C) 1994-2022 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.
@@ -250,7 +250,7 @@ rl_gather_tyi (void)
register int tem, result;
int chars_avail, k;
char input;
#if defined(HAVE_SELECT)
#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
fd_set readfds, exceptfds;
struct timeval timeout;
#endif
@@ -807,7 +807,7 @@ rl_getc (FILE *stream)
int result;
unsigned char c;
int fd;
#if defined (HAVE_PSELECT)
#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
sigset_t empty_set;
fd_set readfds;
#endif
+1 -1
View File
@@ -729,7 +729,7 @@ rl_tty_set_echoing (int u)
_rl_echoing_p = u;
return o;
}
/* **************************************************************** */
/* */
/* Bogus Flow Control */
+4 -8
View File
@@ -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-2019 Free Software Foundation, Inc.
/* Copyright (C) 2008,2009-2019,2022 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -33,9 +33,7 @@
# include <sys/file.h>
#endif /* HAVE_SYS_FILE_H */
#if defined (HAVE_PSELECT)
# include <signal.h>
#endif
#include <signal.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
@@ -107,10 +105,8 @@ nchars_avail (fd, nchars)
int nchars;
{
int result, chars_avail;
#if defined(HAVE_SELECT)
fd_set readfds, exceptfds;
#endif
#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
fd_set readfds, exceptfds;
sigset_t set, oset;
#endif
@@ -121,7 +117,7 @@ nchars_avail (fd, nchars)
chars_avail = 0;
#if defined (HAVE_SELECT)
#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
FD_ZERO (&readfds);
FD_ZERO (&exceptfds);
FD_SET (fd, &readfds);
+5 -1
View File
@@ -1,6 +1,6 @@
/* timers - functions to manage shell timers */
/* Copyright (C) 2021 Free Software Foundation, Inc.
/* Copyright (C) 2021,2022 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -47,6 +47,10 @@ extern int errno;
#define FREE(s) do { if (s) free (s); } while (0)
#endif
#ifndef USEC_PER_SEC
# define USEC_PER_SEC 1000000
#endif
extern unsigned int falarm (unsigned int, unsigned int);
static void shtimer_zero (sh_timer *);
+3 -2
View File
@@ -1,6 +1,6 @@
/* ufuncs - sleep and alarm functions that understand fractional values */
/* Copyright (C) 2008,2009-2020 Free Software Foundation, Inc.
/* Copyright (C) 2008,2009-2020,2022 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -33,9 +33,10 @@
extern int errno;
#endif /* !errno */
#include "quit.h"
#if defined (HAVE_SELECT)
# include "posixselect.h"
# include "quit.h"
# include "trap.h"
# include "stat-time.h"
#endif