mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-27 23:53:18 +02:00
bash-4.1 more stray file cleanup
This commit is contained in:
-486
@@ -1,486 +0,0 @@
|
||||
/* pathexp.c -- The shell interface to the globbing library. */
|
||||
|
||||
/* Copyright (C) 1995-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "bashtypes.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "bashansi.h"
|
||||
|
||||
#include "shell.h"
|
||||
#include "pathexp.h"
|
||||
#include "flags.h"
|
||||
|
||||
#include "shmbutil.h"
|
||||
#include "bashintl.h"
|
||||
|
||||
#include <glob/strmatch.h>
|
||||
|
||||
static int glob_name_is_acceptable __P((const char *));
|
||||
static void ignore_globbed_names __P((char **, sh_ignore_func_t *));
|
||||
|
||||
#if defined (USE_POSIX_GLOB_LIBRARY)
|
||||
# include <glob.h>
|
||||
typedef int posix_glob_errfunc_t __P((const char *, int));
|
||||
#else
|
||||
# include <glob/glob.h>
|
||||
#endif
|
||||
|
||||
/* Control whether * matches .files in globbing. */
|
||||
int glob_dot_filenames;
|
||||
|
||||
/* Control whether the extended globbing features are enabled. */
|
||||
int extended_glob = EXTzg;
|
||||
|
||||
/* Control enabling special handling of `**' */
|
||||
int glob_star = 0;
|
||||
|
||||
/* Return nonzero if STRING has any unquoted special globbing chars in it. */
|
||||
int
|
||||
unquoted_glob_pattern_p (string)
|
||||
register char *string;
|
||||
{
|
||||
register int c;
|
||||
char *send;
|
||||
int open;
|
||||
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
open = 0;
|
||||
send = string + strlen (string);
|
||||
|
||||
while (c = *string++)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '?':
|
||||
case '*':
|
||||
return (1);
|
||||
|
||||
case '[':
|
||||
open++;
|
||||
continue;
|
||||
|
||||
case ']':
|
||||
if (open)
|
||||
return (1);
|
||||
continue;
|
||||
|
||||
case '+':
|
||||
case '@':
|
||||
case '!':
|
||||
if (*string == '(') /*)*/
|
||||
return (1);
|
||||
continue;
|
||||
|
||||
case CTLESC:
|
||||
case '\\':
|
||||
if (*string++ == '\0')
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Advance one fewer byte than an entire multibyte character to
|
||||
account for the auto-increment in the loop above. */
|
||||
#ifdef HANDLE_MULTIBYTE
|
||||
string--;
|
||||
ADVANCE_CHAR_P (string, send - string);
|
||||
string++;
|
||||
#else
|
||||
ADVANCE_CHAR_P (string, send - string);
|
||||
#endif
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Return 1 if C is a character that is `special' in a POSIX ERE and needs to
|
||||
be quoted to match itself. */
|
||||
static inline int
|
||||
ere_char (c)
|
||||
int c;
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '.':
|
||||
case '[':
|
||||
case '\\':
|
||||
case '(':
|
||||
case ')':
|
||||
case '*':
|
||||
case '+':
|
||||
case '?':
|
||||
case '{':
|
||||
case '|':
|
||||
case '^':
|
||||
case '$':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
glob_char_p (s)
|
||||
const char *s;
|
||||
{
|
||||
switch (*s)
|
||||
{
|
||||
case '*':
|
||||
case '[':
|
||||
case ']':
|
||||
case '?':
|
||||
case '\\':
|
||||
return 1;
|
||||
case '+':
|
||||
case '@':
|
||||
case '!':
|
||||
if (s[1] == '(') /*(*/
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* PATHNAME can contain characters prefixed by CTLESC; this indicates
|
||||
that the character is to be quoted. We quote it here in the style
|
||||
that the glob library recognizes. If flags includes QGLOB_CVTNULL,
|
||||
we change quoted null strings (pathname[0] == CTLNUL) into empty
|
||||
strings (pathname[0] == 0). If this is called after quote removal
|
||||
is performed, (flags & QGLOB_CVTNULL) should be 0; if called when quote
|
||||
removal has not been done (for example, before attempting to match a
|
||||
pattern while executing a case statement), flags should include
|
||||
QGLOB_CVTNULL. If flags includes QGLOB_FILENAME, appropriate quoting
|
||||
to match a filename should be performed. */
|
||||
char *
|
||||
quote_string_for_globbing (pathname, qflags)
|
||||
const char *pathname;
|
||||
int qflags;
|
||||
{
|
||||
char *temp;
|
||||
register int i, j;
|
||||
|
||||
temp = (char *)xmalloc (strlen (pathname) + 1);
|
||||
|
||||
if ((qflags & QGLOB_CVTNULL) && QUOTED_NULL (pathname))
|
||||
{
|
||||
temp[0] = '\0';
|
||||
return temp;
|
||||
}
|
||||
|
||||
for (i = j = 0; pathname[i]; i++)
|
||||
{
|
||||
if (pathname[i] == CTLESC)
|
||||
{
|
||||
if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/')
|
||||
continue;
|
||||
if ((qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
|
||||
continue;
|
||||
temp[j++] = '\\';
|
||||
i++;
|
||||
if (pathname[i] == '\0')
|
||||
break;
|
||||
}
|
||||
else if (pathname[i] == '\\')
|
||||
{
|
||||
temp[j++] = '\\';
|
||||
i++;
|
||||
if (pathname[i] == '\0')
|
||||
break;
|
||||
}
|
||||
temp[j++] = pathname[i];
|
||||
}
|
||||
temp[j] = '\0';
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
char *
|
||||
quote_globbing_chars (string)
|
||||
char *string;
|
||||
{
|
||||
size_t slen;
|
||||
char *temp, *s, *t, *send;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
slen = strlen (string);
|
||||
send = string + slen;
|
||||
|
||||
temp = (char *)xmalloc (slen * 2 + 1);
|
||||
for (t = temp, s = string; *s; )
|
||||
{
|
||||
if (glob_char_p (s))
|
||||
*t++ = '\\';
|
||||
|
||||
/* Copy a single (possibly multibyte) character from s to t,
|
||||
incrementing both. */
|
||||
COPY_CHAR_P (t, s, send);
|
||||
}
|
||||
*t = '\0';
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* Call the glob library to do globbing on PATHNAME. */
|
||||
char **
|
||||
shell_glob_filename (pathname)
|
||||
const char *pathname;
|
||||
{
|
||||
#if defined (USE_POSIX_GLOB_LIBRARY)
|
||||
register int i;
|
||||
char *temp, **results;
|
||||
glob_t filenames;
|
||||
int glob_flags;
|
||||
|
||||
temp = quote_string_for_globbing (pathname, QGLOB_FILENAME);
|
||||
|
||||
filenames.gl_offs = 0;
|
||||
|
||||
# if defined (GLOB_PERIOD)
|
||||
glob_flags = glob_dot_filenames ? GLOB_PERIOD : 0;
|
||||
# else
|
||||
glob_flags = 0;
|
||||
# endif /* !GLOB_PERIOD */
|
||||
|
||||
glob_flags |= (GLOB_ERR | GLOB_DOOFFS);
|
||||
|
||||
i = glob (temp, glob_flags, (posix_glob_errfunc_t *)NULL, &filenames);
|
||||
|
||||
free (temp);
|
||||
|
||||
if (i == GLOB_NOSPACE || i == GLOB_ABORTED)
|
||||
return ((char **)NULL);
|
||||
else if (i == GLOB_NOMATCH)
|
||||
filenames.gl_pathv = (char **)NULL;
|
||||
else if (i != 0) /* other error codes not in POSIX.2 */
|
||||
filenames.gl_pathv = (char **)NULL;
|
||||
|
||||
results = filenames.gl_pathv;
|
||||
|
||||
if (results && ((GLOB_FAILED (results)) == 0))
|
||||
{
|
||||
if (should_ignore_glob_matches ())
|
||||
ignore_glob_matches (results);
|
||||
if (results && results[0])
|
||||
strvec_sort (results);
|
||||
else
|
||||
{
|
||||
FREE (results);
|
||||
results = (char **)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (results);
|
||||
|
||||
#else /* !USE_POSIX_GLOB_LIBRARY */
|
||||
|
||||
char *temp, **results;
|
||||
|
||||
noglob_dot_filenames = glob_dot_filenames == 0;
|
||||
|
||||
temp = quote_string_for_globbing (pathname, QGLOB_FILENAME);
|
||||
results = glob_filename (temp, glob_star ? GX_GLOBSTAR : 0);
|
||||
free (temp);
|
||||
|
||||
if (results && ((GLOB_FAILED (results)) == 0))
|
||||
{
|
||||
if (should_ignore_glob_matches ())
|
||||
ignore_glob_matches (results);
|
||||
if (results && results[0])
|
||||
strvec_sort (results);
|
||||
else
|
||||
{
|
||||
FREE (results);
|
||||
results = (char **)&glob_error_return;
|
||||
}
|
||||
}
|
||||
|
||||
return (results);
|
||||
#endif /* !USE_POSIX_GLOB_LIBRARY */
|
||||
}
|
||||
|
||||
/* Stuff for GLOBIGNORE. */
|
||||
|
||||
static struct ignorevar globignore =
|
||||
{
|
||||
"GLOBIGNORE",
|
||||
(struct ign *)0,
|
||||
0,
|
||||
(char *)0,
|
||||
(sh_iv_item_func_t *)0,
|
||||
};
|
||||
|
||||
/* Set up to ignore some glob matches because the value of GLOBIGNORE
|
||||
has changed. If GLOBIGNORE is being unset, we also need to disable
|
||||
the globbing of filenames beginning with a `.'. */
|
||||
void
|
||||
setup_glob_ignore (name)
|
||||
char *name;
|
||||
{
|
||||
char *v;
|
||||
|
||||
v = get_string_value (name);
|
||||
setup_ignore_patterns (&globignore);
|
||||
|
||||
if (globignore.num_ignores)
|
||||
glob_dot_filenames = 1;
|
||||
else if (v == 0)
|
||||
glob_dot_filenames = 0;
|
||||
}
|
||||
|
||||
int
|
||||
should_ignore_glob_matches ()
|
||||
{
|
||||
return globignore.num_ignores;
|
||||
}
|
||||
|
||||
/* Return 0 if NAME matches a pattern in the globignore.ignores list. */
|
||||
static int
|
||||
glob_name_is_acceptable (name)
|
||||
const char *name;
|
||||
{
|
||||
struct ign *p;
|
||||
int flags;
|
||||
|
||||
/* . and .. are never matched */
|
||||
if (name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
|
||||
return (0);
|
||||
|
||||
flags = FNM_PATHNAME | FNMATCH_EXTFLAG;
|
||||
for (p = globignore.ignores; p->val; p++)
|
||||
{
|
||||
if (strmatch (p->val, (char *)name, flags) != FNM_NOMATCH)
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Internal function to test whether filenames in NAMES should be
|
||||
ignored. NAME_FUNC is a pointer to a function to call with each
|
||||
name. It returns non-zero if the name is acceptable to the particular
|
||||
ignore function which called _ignore_names; zero if the name should
|
||||
be removed from NAMES. */
|
||||
|
||||
static void
|
||||
ignore_globbed_names (names, name_func)
|
||||
char **names;
|
||||
sh_ignore_func_t *name_func;
|
||||
{
|
||||
char **newnames;
|
||||
int n, i;
|
||||
|
||||
for (i = 0; names[i]; i++)
|
||||
;
|
||||
newnames = strvec_create (i + 1);
|
||||
|
||||
for (n = i = 0; names[i]; i++)
|
||||
{
|
||||
if ((*name_func) (names[i]))
|
||||
newnames[n++] = names[i];
|
||||
else
|
||||
free (names[i]);
|
||||
}
|
||||
|
||||
newnames[n] = (char *)NULL;
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
names[0] = (char *)NULL;
|
||||
free (newnames);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy the acceptable names from NEWNAMES back to NAMES and set the
|
||||
new array end. */
|
||||
for (n = 0; newnames[n]; n++)
|
||||
names[n] = newnames[n];
|
||||
names[n] = (char *)NULL;
|
||||
free (newnames);
|
||||
}
|
||||
|
||||
void
|
||||
ignore_glob_matches (names)
|
||||
char **names;
|
||||
{
|
||||
if (globignore.num_ignores == 0)
|
||||
return;
|
||||
|
||||
ignore_globbed_names (names, glob_name_is_acceptable);
|
||||
}
|
||||
|
||||
void
|
||||
setup_ignore_patterns (ivp)
|
||||
struct ignorevar *ivp;
|
||||
{
|
||||
int numitems, maxitems, ptr;
|
||||
char *colon_bit, *this_ignoreval;
|
||||
struct ign *p;
|
||||
|
||||
this_ignoreval = get_string_value (ivp->varname);
|
||||
|
||||
/* If nothing has changed then just exit now. */
|
||||
if ((this_ignoreval && ivp->last_ignoreval && STREQ (this_ignoreval, ivp->last_ignoreval)) ||
|
||||
(!this_ignoreval && !ivp->last_ignoreval))
|
||||
return;
|
||||
|
||||
/* Oops. The ignore variable has changed. Re-parse it. */
|
||||
ivp->num_ignores = 0;
|
||||
|
||||
if (ivp->ignores)
|
||||
{
|
||||
for (p = ivp->ignores; p->val; p++)
|
||||
free(p->val);
|
||||
free (ivp->ignores);
|
||||
ivp->ignores = (struct ign *)NULL;
|
||||
}
|
||||
|
||||
if (ivp->last_ignoreval)
|
||||
{
|
||||
free (ivp->last_ignoreval);
|
||||
ivp->last_ignoreval = (char *)NULL;
|
||||
}
|
||||
|
||||
if (this_ignoreval == 0 || *this_ignoreval == '\0')
|
||||
return;
|
||||
|
||||
ivp->last_ignoreval = savestring (this_ignoreval);
|
||||
|
||||
numitems = maxitems = ptr = 0;
|
||||
|
||||
while (colon_bit = extract_colon_unit (this_ignoreval, &ptr))
|
||||
{
|
||||
if (numitems + 1 >= maxitems)
|
||||
{
|
||||
maxitems += 10;
|
||||
ivp->ignores = (struct ign *)xrealloc (ivp->ignores, maxitems * sizeof (struct ign));
|
||||
}
|
||||
ivp->ignores[numitems].val = colon_bit;
|
||||
ivp->ignores[numitems].len = strlen (colon_bit);
|
||||
ivp->ignores[numitems].flags = 0;
|
||||
if (ivp->item_func)
|
||||
(*ivp->item_func) (&ivp->ignores[numitems]);
|
||||
numitems++;
|
||||
}
|
||||
ivp->ignores[numitems].val = (char *)NULL;
|
||||
ivp->num_ignores = numitems;
|
||||
}
|
||||
-6440
File diff suppressed because it is too large
Load Diff
@@ -1,13 +0,0 @@
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -1,12 +0,0 @@
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
@@ -1,13 +0,0 @@
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
@@ -1,286 +0,0 @@
|
||||
*** ../bash-20090903/redir.c 2009-08-17 17:46:34.000000000 -0400
|
||||
--- redir.c 2009-09-11 17:29:54.000000000 -0400
|
||||
***************
|
||||
*** 99,111 ****
|
||||
int oflags;
|
||||
|
||||
allocname = 0;
|
||||
! if (temp->redirector < 0)
|
||||
/* This can happen when read_token_word encounters overflow, like in
|
||||
exec 4294967297>x */
|
||||
filename = _("file descriptor out of range");
|
||||
#ifdef EBADF
|
||||
/* This error can never involve NOCLOBBER */
|
||||
! else if (error != NOCLOBBER_REDIRECT && temp->redirector >= 0 && error == EBADF)
|
||||
{
|
||||
/* If we're dealing with two file descriptors, we have to guess about
|
||||
which one is invalid; in the cases of r_{duplicating,move}_input and
|
||||
--- 99,113 ----
|
||||
int oflags;
|
||||
|
||||
allocname = 0;
|
||||
! if (temp->rflags & REDIR_VARASSIGN)
|
||||
! filename = savestring (temp->redirector.filename->word);
|
||||
! else if (temp->redirector.dest < 0)
|
||||
/* This can happen when read_token_word encounters overflow, like in
|
||||
exec 4294967297>x */
|
||||
filename = _("file descriptor out of range");
|
||||
#ifdef EBADF
|
||||
/* This error can never involve NOCLOBBER */
|
||||
! else if (error != NOCLOBBER_REDIRECT && temp->redirector.dest >= 0 && error == EBADF)
|
||||
{
|
||||
/* If we're dealing with two file descriptors, we have to guess about
|
||||
which one is invalid; in the cases of r_{duplicating,move}_input and
|
||||
***************
|
||||
*** 119,125 ****
|
||||
filename = allocname = itos (temp->redirectee.dest);
|
||||
break;
|
||||
default:
|
||||
! filename = allocname = itos (temp->redirector);
|
||||
break;
|
||||
}
|
||||
}
|
||||
--- 121,127 ----
|
||||
filename = allocname = itos (temp->redirectee.dest);
|
||||
break;
|
||||
default:
|
||||
! filename = allocname = itos (temp->redirector.dest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
***************
|
||||
*** 162,167 ****
|
||||
--- 164,173 ----
|
||||
internal_error (_("cannot create temp file for here-document: %s"), strerror (heredoc_errno));
|
||||
break;
|
||||
|
||||
+ case BADVAR_REDIRECT:
|
||||
+ internal_error (_("cannot assign fd to variable %s"), filename);
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
internal_error ("%s: %s", filename, strerror (error));
|
||||
break;
|
||||
***************
|
||||
*** 649,658 ****
|
||||
char *redirectee_word;
|
||||
enum r_instruction ri;
|
||||
REDIRECT *new_redirect;
|
||||
|
||||
redirectee = redirect->redirectee.filename;
|
||||
redir_fd = redirect->redirectee.dest;
|
||||
! redirector = redirect->redirector;
|
||||
ri = redirect->instruction;
|
||||
|
||||
if (redirect->flags & RX_INTERNAL)
|
||||
--- 655,665 ----
|
||||
char *redirectee_word;
|
||||
enum r_instruction ri;
|
||||
REDIRECT *new_redirect;
|
||||
+ REDIRECTEE sd;
|
||||
|
||||
redirectee = redirect->redirectee.filename;
|
||||
redir_fd = redirect->redirectee.dest;
|
||||
! redirector = redirect->redirector.dest;
|
||||
ri = redirect->instruction;
|
||||
|
||||
if (redirect->flags & RX_INTERNAL)
|
||||
***************
|
||||
*** 670,680 ****
|
||||
return (AMBIGUOUS_REDIRECT);
|
||||
else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
|
||||
{
|
||||
rd.dest = 0;
|
||||
! new_redirect = make_redirection (redirector, r_close_this, rd);
|
||||
}
|
||||
else if (all_digits (redirectee_word))
|
||||
{
|
||||
if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd)
|
||||
rd.dest = lfd;
|
||||
else
|
||||
--- 677,689 ----
|
||||
return (AMBIGUOUS_REDIRECT);
|
||||
else if (redirectee_word[0] == '-' && redirectee_word[1] == '\0')
|
||||
{
|
||||
+ sd.dest = redirector;
|
||||
rd.dest = 0;
|
||||
! new_redirect = make_redirection (sd, r_close_this, rd, 0);
|
||||
}
|
||||
else if (all_digits (redirectee_word))
|
||||
{
|
||||
+ sd.dest = redirector;
|
||||
if (legal_number (redirectee_word, &lfd) && (int)lfd == lfd)
|
||||
rd.dest = lfd;
|
||||
else
|
||||
***************
|
||||
*** 682,704 ****
|
||||
switch (ri)
|
||||
{
|
||||
case r_duplicating_input_word:
|
||||
! new_redirect = make_redirection (redirector, r_duplicating_input, rd);
|
||||
break;
|
||||
case r_duplicating_output_word:
|
||||
! new_redirect = make_redirection (redirector, r_duplicating_output, rd);
|
||||
break;
|
||||
case r_move_input_word:
|
||||
! new_redirect = make_redirection (redirector, r_move_input, rd);
|
||||
break;
|
||||
case r_move_output_word:
|
||||
! new_redirect = make_redirection (redirector, r_move_output, rd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ri == r_duplicating_output_word && redirector == 1)
|
||||
{
|
||||
rd.filename = make_bare_word (redirectee_word);
|
||||
! new_redirect = make_redirection (1, r_err_and_out, rd);
|
||||
}
|
||||
else
|
||||
{
|
||||
--- 691,714 ----
|
||||
switch (ri)
|
||||
{
|
||||
case r_duplicating_input_word:
|
||||
! new_redirect = make_redirection (sd, r_duplicating_input, rd, 0);
|
||||
break;
|
||||
case r_duplicating_output_word:
|
||||
! new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
|
||||
break;
|
||||
case r_move_input_word:
|
||||
! new_redirect = make_redirection (sd, r_move_input, rd, 0);
|
||||
break;
|
||||
case r_move_output_word:
|
||||
! new_redirect = make_redirection (sd, r_move_output, rd, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ri == r_duplicating_output_word && redirector == 1)
|
||||
{
|
||||
+ sd.dest = 1;
|
||||
rd.filename = make_bare_word (redirectee_word);
|
||||
! new_redirect = make_redirection (sd, r_err_and_out, rd, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
***************
|
||||
*** 730,736 ****
|
||||
redirectee = new_redirect->redirectee.filename;
|
||||
|
||||
redir_fd = new_redirect->redirectee.dest;
|
||||
! redirector = new_redirect->redirector;
|
||||
ri = new_redirect->instruction;
|
||||
|
||||
/* Overwrite the flags element of the old redirect with the new value. */
|
||||
--- 740,746 ----
|
||||
redirectee = new_redirect->redirectee.filename;
|
||||
|
||||
redir_fd = new_redirect->redirectee.dest;
|
||||
! redirector = new_redirect->redirector.dest;
|
||||
ri = new_redirect->instruction;
|
||||
|
||||
/* Overwrite the flags element of the old redirect with the new value. */
|
||||
***************
|
||||
*** 1021,1026 ****
|
||||
--- 1031,1037 ----
|
||||
{
|
||||
int new_fd, clexec_flag;
|
||||
REDIRECT *new_redirect, *closer, *dummy_redirect;
|
||||
+ REDIRECTEE sd;
|
||||
|
||||
new_fd = fcntl (fd, F_DUPFD, (fdbase < SHELL_FD_BASE) ? SHELL_FD_BASE : fdbase+1);
|
||||
if (new_fd < 0)
|
||||
***************
|
||||
*** 1034,1049 ****
|
||||
|
||||
clexec_flag = fcntl (fd, F_GETFD, 0);
|
||||
|
||||
rd.dest = 0;
|
||||
! closer = make_redirection (new_fd, r_close_this, rd);
|
||||
closer->flags |= RX_INTERNAL;
|
||||
dummy_redirect = copy_redirects (closer);
|
||||
|
||||
rd.dest = new_fd;
|
||||
if (fd == 0)
|
||||
! new_redirect = make_redirection (fd, r_duplicating_input, rd);
|
||||
else
|
||||
! new_redirect = make_redirection (fd, r_duplicating_output, rd);
|
||||
new_redirect->flags |= RX_INTERNAL;
|
||||
if (clexec_flag == 0 && fd >= 3 && new_fd >= SHELL_FD_BASE)
|
||||
new_redirect->flags |= RX_SAVCLEXEC;
|
||||
--- 1045,1062 ----
|
||||
|
||||
clexec_flag = fcntl (fd, F_GETFD, 0);
|
||||
|
||||
+ sd.dest = new_fd;
|
||||
rd.dest = 0;
|
||||
! closer = make_redirection (sd, r_close_this, rd, 0);
|
||||
closer->flags |= RX_INTERNAL;
|
||||
dummy_redirect = copy_redirects (closer);
|
||||
|
||||
+ sd.dest = fd;
|
||||
rd.dest = new_fd;
|
||||
if (fd == 0)
|
||||
! new_redirect = make_redirection (sd, r_duplicating_input, rd, 0);
|
||||
else
|
||||
! new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
|
||||
new_redirect->flags |= RX_INTERNAL;
|
||||
if (clexec_flag == 0 && fd >= 3 && new_fd >= SHELL_FD_BASE)
|
||||
new_redirect->flags |= RX_SAVCLEXEC;
|
||||
***************
|
||||
*** 1066,1073 ****
|
||||
to save others. */
|
||||
if (fd >= SHELL_FD_BASE && ri != r_close_this && clexec_flag)
|
||||
{
|
||||
rd.dest = new_fd;
|
||||
! new_redirect = make_redirection (fd, r_duplicating_output, rd);
|
||||
new_redirect->flags |= RX_INTERNAL;
|
||||
|
||||
add_exec_redirect (new_redirect);
|
||||
--- 1079,1087 ----
|
||||
to save others. */
|
||||
if (fd >= SHELL_FD_BASE && ri != r_close_this && clexec_flag)
|
||||
{
|
||||
+ sd.dest = fd;
|
||||
rd.dest = new_fd;
|
||||
! new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
|
||||
new_redirect->flags |= RX_INTERNAL;
|
||||
|
||||
add_exec_redirect (new_redirect);
|
||||
***************
|
||||
*** 1096,1104 ****
|
||||
int fd;
|
||||
{
|
||||
REDIRECT *closer;
|
||||
|
||||
rd.dest = 0;
|
||||
! closer = make_redirection (fd, r_close_this, rd);
|
||||
closer->flags |= RX_INTERNAL;
|
||||
closer->next = redirection_undo_list;
|
||||
redirection_undo_list = closer;
|
||||
--- 1110,1120 ----
|
||||
int fd;
|
||||
{
|
||||
REDIRECT *closer;
|
||||
+ REDIRECTEE sd;
|
||||
|
||||
+ sd.dest = fd;
|
||||
rd.dest = 0;
|
||||
! closer = make_redirection (sd, r_close_this, rd, 0);
|
||||
closer->flags |= RX_INTERNAL;
|
||||
closer->next = redirection_undo_list;
|
||||
redirection_undo_list = closer;
|
||||
***************
|
||||
*** 1154,1159 ****
|
||||
int n;
|
||||
|
||||
for (n = 0, rp = redirs; rp; rp = rp->next)
|
||||
! n += stdin_redirection (rp->instruction, rp->redirector);
|
||||
return n;
|
||||
}
|
||||
--- 1170,1175 ----
|
||||
int n;
|
||||
|
||||
for (n = 0, rp = redirs; rp; rp = rp->next)
|
||||
! n += stdin_redirection (rp->instruction, rp->redirector.dest);
|
||||
return n;
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
*** array.c 2009-03-29 17:21:09.000000000 -0400
|
||||
--- array.c.save3 2009-03-28 18:16:49.000000000 -0400
|
||||
***************
|
||||
*** 56,59 ****
|
||||
--- 56,84 ----
|
||||
static char *array_to_string_internal __P((ARRAY_ELEMENT *, ARRAY_ELEMENT *, char *, int));
|
||||
|
||||
+ static ARRAY *lastarray = 0;
|
||||
+ static ARRAY_ELEMENT *lastref = 0;
|
||||
+
|
||||
+ #define IS_LASTREF(a) ((a) == lastarray)
|
||||
+
|
||||
+ #define INVALIDATE_LASTREF(a) \
|
||||
+ do { \
|
||||
+ if ((a) == lastarray) { \
|
||||
+ lastarray = 0; \
|
||||
+ lastref = 0; \
|
||||
+ } \
|
||||
+ } while (0)
|
||||
+
|
||||
+ #define SET_LASTREF(a, e) \
|
||||
+ do { \
|
||||
+ lastarray = (a); \
|
||||
+ lastref = (e); \
|
||||
+ } while (0)
|
||||
+
|
||||
+ #define UNSET_LASTREF() \
|
||||
+ do { \
|
||||
+ lastarray = 0; \
|
||||
+ lastref = 0; \
|
||||
+ } while (0)
|
||||
+
|
||||
ARRAY *
|
||||
array_create()
|
||||
***************
|
||||
*** 88,91 ****
|
||||
--- 113,117 ----
|
||||
a->max_index = -1;
|
||||
a->num_elements = 0;
|
||||
+ INVALIDATE_LASTREF(a);
|
||||
}
|
||||
|
||||
***************
|
||||
*** 186,189 ****
|
||||
--- 212,216 ----
|
||||
return ((ARRAY_ELEMENT *)NULL);
|
||||
|
||||
+ INVALIDATE_LASTREF(a);
|
||||
for (i = 0, ret = ae = element_forw(a->head); ae != a->head && i < n; ae = element_forw(ae), i++)
|
||||
;
|
||||
***************
|
||||
*** 264,267 ****
|
||||
--- 291,295 ----
|
||||
a->max_index = element_index(a->head->prev);
|
||||
|
||||
+ INVALIDATE_LASTREF(a);
|
||||
return (a->num_elements);
|
||||
}
|
||||
***************
|
||||
*** 595,598 ****
|
||||
--- 623,627 ----
|
||||
a->max_index = i;
|
||||
a->num_elements++;
|
||||
+ SET_LASTREF(a, new);
|
||||
return(0);
|
||||
}
|
||||
***************
|
||||
*** 608,618 ****
|
||||
--- 637,650 ----
|
||||
free(element_value(ae));
|
||||
ae->value = v ? savestring(v) : (char *)NULL;
|
||||
+ SET_LASTREF(a, ae);
|
||||
return(0);
|
||||
} else if (element_index(ae) > i) {
|
||||
ADD_BEFORE(ae, new);
|
||||
a->num_elements++;
|
||||
+ SET_LASTREF(a, new);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
+ INVALIDATE_LASTREF(a);
|
||||
return (-1); /* problem */
|
||||
}
|
||||
***************
|
||||
*** 638,641 ****
|
||||
--- 670,674 ----
|
||||
if (i == array_max_index(a))
|
||||
a->max_index = element_index(ae->prev);
|
||||
+ INVALIDATE_LASTREF(a);
|
||||
return(ae);
|
||||
}
|
||||
***************
|
||||
*** 655,661 ****
|
||||
if (a == 0 || array_empty(a))
|
||||
return((char *) NULL);
|
||||
! for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
|
||||
! if (element_index(ae) == i)
|
||||
return(element_value(ae));
|
||||
return((char *) NULL);
|
||||
}
|
||||
--- 688,704 ----
|
||||
if (a == 0 || array_empty(a))
|
||||
return((char *) NULL);
|
||||
! if (i > array_max_index(a))
|
||||
! return ((char *)NULL);
|
||||
! /* Keep roving pointer into array to optimize sequential access */
|
||||
! if (lastref && IS_LASTREF(a))
|
||||
! ae = (i >= element_index(lastref)) ? lastref : element_forw(a->head);
|
||||
! else
|
||||
! ae = element_forw(a->head);
|
||||
! for ( ; ae != a->head; ae = element_forw(ae))
|
||||
! if (element_index(ae) == i) {
|
||||
! SET_LASTREF(a, ae);
|
||||
return(element_value(ae));
|
||||
+ }
|
||||
+ UNSET_LASTREF();
|
||||
return((char *) NULL);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
Readline is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Readline is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Readline. If not, see <http://www.gnu.org/licenses/>.
|
||||
@@ -1,12 +0,0 @@
|
||||
History is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
History is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with History. If not, see <http://www.gnu.org/licenses/>.
|
||||
@@ -1,59 +0,0 @@
|
||||
*** ../bash-4.0-patched/lib/readline/complete.c 2009-01-22 15:15:14.000000000 -0500
|
||||
--- lib/readline/complete.c 2009-08-26 17:15:59.000000000 -0400
|
||||
***************
|
||||
*** 2209,2213 ****
|
||||
/* The first time through, we generate the list of matches and set things
|
||||
up to insert them. */
|
||||
! if (rl_last_func != rl_menu_complete)
|
||||
{
|
||||
/* Clean up from previous call, if any. */
|
||||
--- 2252,2256 ----
|
||||
/* The first time through, we generate the list of matches and set things
|
||||
up to insert them. */
|
||||
! if (rl_last_func != rl_old_menu_complete)
|
||||
{
|
||||
/* Clean up from previous call, if any. */
|
||||
***************
|
||||
*** 2221,2224 ****
|
||||
--- 2264,2269 ----
|
||||
rl_completion_invoking_key = invoking_key;
|
||||
|
||||
+ RL_SETSTATE(RL_STATE_COMPLETING);
|
||||
+
|
||||
/* Only the completion entry function can change these. */
|
||||
set_completion_defaults ('%');
|
||||
***************
|
||||
*** 2260,2266 ****
|
||||
--- 2305,2314 ----
|
||||
orig_text = (char *)0;
|
||||
completion_changed_buffer = 0;
|
||||
+ RL_UNSETSTATE(RL_STATE_COMPLETING);
|
||||
return (0);
|
||||
}
|
||||
|
||||
+ RL_UNSETSTATE(RL_STATE_COMPLETING);
|
||||
+
|
||||
for (match_list_size = 0; matches[match_list_size]; match_list_size++)
|
||||
;
|
||||
***************
|
||||
*** 2338,2341 ****
|
||||
--- 2386,2391 ----
|
||||
full_completion = 0;
|
||||
|
||||
+ RL_SETSTATE(RL_STATE_COMPLETING);
|
||||
+
|
||||
/* Only the completion entry function can change these. */
|
||||
set_completion_defaults ('%');
|
||||
***************
|
||||
*** 2379,2385 ****
|
||||
--- 2429,2438 ----
|
||||
orig_text = (char *)0;
|
||||
completion_changed_buffer = 0;
|
||||
+ RL_UNSETSTATE(RL_STATE_COMPLETING);
|
||||
return (0);
|
||||
}
|
||||
|
||||
+ RL_UNSETSTATE(RL_STATE_COMPLETING);
|
||||
+
|
||||
for (match_list_size = 0; matches[match_list_size]; match_list_size++)
|
||||
;
|
||||
Reference in New Issue
Block a user