commit bash-20070523 snapshot

This commit is contained in:
Chet Ramey
2011-12-07 09:08:27 -05:00
parent d7f499903c
commit b0c16657b4
63 changed files with 2904 additions and 149 deletions
+90 -2
View File
@@ -14577,7 +14577,8 @@ subst.c
memory. If word expansions (particularly brace expansions) are
required, the expansion code will free the string passed to
expand_word_internal, and we don't want to free unallocated memory
(patstr++) or have duplicate frees (patstr)
(patstr++) or have duplicate frees (patstr). Fixes bug reported on
Red Hat bugzilla
5/9
---
@@ -14604,10 +14605,97 @@ execute_cmd.c
and restored by execute_simple_command
subst.c
- new variablem, assigning_in_environment, set and unset around calls
- new variable, assigning_in_environment, set and unset around calls
to assign_in_env by the expansion code
variables.c
- use executing_builtin and assigning_in_environment to decide whether
or not to look into temporary_env when calling find_variable_internal.
Fixes problem reported by Kevin Quinn <kevquinn@gentoo.org>
5/22
----
redir.c
- change add_undo_redirect to differentiate between file descriptors
greater than SHELL_FD_BASE (currently 10) used internally to save
others and then being the targets of user redirection and fds that
are just the target of user redirections. The former need to have
an `exec undo' redirect added to undo it in case exec throws away
redirections; the latter does not. We use the close-on-exec flag
for this: if it's set, we assume that the file descriptor is being
used internally to save another. Fixes problem reported by Ian
Jackson <ian@davenant.greenend.org.uk>
shell.c
- new function, init_interactive_script(), does interactive initialization
for a script run with `bash -i script' -- does everything the same
as init_interactive except set `interactive == 1', which causes the
shell to read from the standard input, after calling
init_noninteractive
- call init_interactive_script if a script is run as `bash -i script'.
Fixes problem reported by Joseph Michaud <jmichaud@sgi.com>
5/24
----
builtins/printf.def
- change vbadd to only call FASTCOPY if the passed buffer length is
> 1
- if the `-v' option is supplied and `vbuf' is already non-null from a
previous `printf -v var' call, set vbuf[0]=0 explicitly instead of
relying on vbadd to do it -- vbadd may not be called.
- fix PRETURN macro to set vbuf[0] == 0 if vbuf is not freed. These
should fix problem reported by Elmar Stellnberger <estellnb@yahoo.de>
lib/readline/display.c
- fix update_line to deal with the case where col_lendiff > 0 (meaning
the new string takes up more screen real estate than the old) but
lendiff < 0 (meaning that it takes fewer bytes to do so). This can
happen when a multibyte prompt string is replaced with a longer one
containing only single-byte characters (e.g., when doing a reverse
i-search). Fixes gentoo bug reported by Peter Volkov
<torre_cremata@mail.ru>
builtins/read.def
- make sure we only print $PS2 if the standard input is a terminal
- new function, read_mbchar, to read a multibyte character so we
can make sure we read entire multibyte chars when `read -n' is
used, rather than bytes. Only called when -n is supplied.
Fixes problem reported by Stanislav Brabec <sbrabec@suse.cz>
5/25
----
externs.h
- new #defines for third argument to named_function_string:
FUNC_MULTILINE (don't suppress newlines) and FUNC_EXTERNAL (convert
to external display form)
subst.h
- new extern declaration for remove_quoted_escapes
subst.c
- remove_quoted_escapes is now global
print_cmd.c
- in named_function_string, if FUNC_EXTERNAL is in the flags argument,
call remove_quoted_escapes to convert from internal to external form.
Fixes bug reported by Bo Andresen <bo.andresen@zlin.dk>
variables.c,builtins/{declare,setattr,type}.def
- use FUNC_MULTILINE in calls to named_function_string as appropriate
- add FUNC_EXTERNAL to calls to named_function_string as appropriate
5/27
----
{make_cmd,variables}.c
- changes to enable the shell to compile when debugger support is
configured out (function_def hash table and access functions). Fixes
bug reported by Horst Wente <horst.wente@acm.org>
builtins/help.def
- fix bug in `help' two-column printing to avoid referencing
shell_builtins[num_shell_builtins]
error.c
- in get_name_for_error, use dollar_vars[0] if the name returned from
looking in $BASH_SOURCE[0] is the empty string as well as if it's
null
+101 -1
View File
@@ -14577,7 +14577,8 @@ subst.c
memory. If word expansions (particularly brace expansions) are
required, the expansion code will free the string passed to
expand_word_internal, and we don't want to free unallocated memory
(patstr++) or have duplicate frees (patstr)
(patstr++) or have duplicate frees (patstr). Fixes bug reported on
Red Hat bugzilla
5/9
---
@@ -14594,3 +14595,102 @@ jobs.c
- change reset_job_indices to avoid infinite looping when js.j_firstj
== 0 or js.j_firstj == js.j_jobslots upon function entry. Fixes
bug reported by osicka@post.cz
5/20
----
execute_cmd.c
- new variable, executing_builtin, keeps track of number of "levels"
of builtins being executed; incremented by execute_builtin; saved
and restored by execute_simple_command
subst.c
- new variable, assigning_in_environment, set and unset around calls
to assign_in_env by the expansion code
variables.c
- use executing_builtin and assigning_in_environment to decide whether
or not to look into temporary_env when calling find_variable_internal.
Fixes problem reported by Kevin Quinn <kevquinn@gentoo.org>
5/22
----
redir.c
- change add_undo_redirect to differentiate between file descriptors
greater than SHELL_FD_BASE (currently 10) used internally to save
others and then being the targets of user redirection and fds that
are just the target of user redirections. The former need to have
an `exec undo' redirect added to undo it in case exec throws away
redirections; the latter does not. We use the close-on-exec flag
for this: if it's set, we assume that the file descriptor is being
used internally to save another. Fixes problem reported by Ian
Jackson <ian@davenant.greenend.org.uk>
shell.c
- new function, init_interactive_script(), does interactive initialization
for a script run with `bash -i script' -- does everything the same
as init_interactive except set `interactive == 1', which causes the
shell to read from the standard input, after calling
init_noninteractive
- call init_interactive_script if a script is run as `bash -i script'.
Fixes problem reported by Joseph Michaud <jmichaud@sgi.com>
5/24
----
builtins/printf.def
- change vbadd to only call FASTCOPY if the passed buffer length is
> 1
- if the `-v' option is supplied and `vbuf' is already non-null from a
previous `printf -v var' call, set vbuf[0]=0 explicitly instead of
relying on vbadd to do it -- vbadd may not be called.
- fix PRETURN macro to set vbuf[0] == 0 if vbuf is not freed. These
should fix problem reported by Elmar Stellnberger <estellnb@yahoo.de>
lib/readline/display.c
- fix update_line to deal with the case where col_lendiff > 0 (meaning
the new string takes up more screen real estate than the old) but
lendiff < 0 (meaning that it takes fewer bytes to do so). This can
happen when a multibyte prompt string is replaced with a longer one
containing only single-byte characters (e.g., when doing a reverse
i-search). Fixes gentoo bug reported by Peter Volkov
<torre_cremata@mail.ru>
builtins/read.def
- make sure we only print $PS2 if the standard input is a terminal
- new function, read_mbchar, to read a multibyte character so we
can make sure we read entire multibyte chars when `read -n' is
used, rather than bytes. Only called when -n is supplied.
Fixes problem reported by Stanislav Brabec <sbrabec@suse.cz>
5/25
----
externs.h
- new #defines for third argument to named_function_string:
FUNC_MULTILINE (don't suppress newlines) and FUNC_EXTERNAL (convert
to external display form)
subst.h
- new extern declaration for remove_quoted_escapes
subst.c
- remove_quoted_escapes is now global
print_cmd.c
- in named_function_string, if FUNC_EXTERNAL is in the flags argument,
call remove_quoted_escapes to convert from internal to external form.
Fixes bug reported by Bo Andresen <bo.andresen@zlin.dk>
variables.c,builtins/{declare,setattr,type}.def
- use FUNC_MULTILINE in calls to named_function_string as appropriate
- add FUNC_EXTERNAL to calls to named_function_string as appropriate
5/27
----
{make_cmd,variables}.c
- changes to enable the shell to compile when debugger support is
configured out (function_def hash table and access functions). Fixes
bug reported by Horst Wente <horst.wente@acm.org>
builtins/help.def
- fix bug in `help' two-column printing to avoid referencing
shell_builtins[num_shell_builtins]
+3
View File
@@ -754,6 +754,7 @@ tests/exec7.sub f
tests/exp.tests f
tests/exp.right f
tests/exp1.sub f
tests/exp2.sub f
tests/extglob.tests f
tests/extglob.right f
tests/extglob1.sub f
@@ -795,6 +796,7 @@ tests/input-line.sh f
tests/input-line.sub f
tests/input.right f
tests/intl.tests f
tests/intl1.sub f
tests/intl.right f
tests/iquote.tests f
tests/iquote.right f
@@ -857,6 +859,7 @@ tests/redir4.in1 f
tests/redir5.sub f
tests/redir6.sub f
tests/redir7.sub f
tests/redir8.sub f
tests/rhs-exp.tests f
tests/rhs-exp.right f
tests/rsh.tests f
+2
View File
@@ -754,6 +754,7 @@ tests/exec7.sub f
tests/exp.tests f
tests/exp.right f
tests/exp1.sub f
tests/exp2.sub f
tests/extglob.tests f
tests/extglob.right f
tests/extglob1.sub f
@@ -857,6 +858,7 @@ tests/redir4.in1 f
tests/redir5.sub f
tests/redir6.sub f
tests/redir7.sub f
tests/redir8.sub f
tests/rhs-exp.tests f
tests/rhs-exp.right f
tests/rsh.tests f
+2 -2
View File
@@ -1,7 +1,7 @@
This file is declare.def, from which is created declare.c.
It implements the builtins "declare" and "local" in Bash.
Copyright (C) 1987-2006 Free Software Foundation, Inc.
Copyright (C) 1987-2007 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -332,7 +332,7 @@ declare_internal (list, local_var)
#endif /* DEBUGGER */
{
t = nodefs ? var->name
: named_function_string (name, function_cell (var), 1);
: named_function_string (name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL);
printf ("%s\n", t);
any_failed = sh_chkwrite (any_failed);
}
+10 -12
View File
@@ -1,7 +1,7 @@
This file is declare.def, from which is created declare.c.
It implements the builtins "declare" and "local" in Bash.
Copyright (C) 1987-2004 Free Software Foundation, Inc.
Copyright (C) 1987-2006 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -89,10 +89,11 @@ declare_builtin (list)
$BUILTIN local
$FUNCTION local_builtin
$SHORT_DOC local name[=value] ...
$SHORT_DOC local [option] name[=value] ...
Create a local variable called NAME, and give it VALUE. LOCAL
can only be used within a function; it makes the variable NAME
have a visible scope restricted to that function and its children.
OPTION can be any of the options accepted by `declare'.
$END
int
local_builtin (list)
@@ -190,16 +191,12 @@ declare_internal (list, local_var)
free (vlist);
}
}
else if (flags_on == 0)
return (set_builtin ((WORD_LIST *)NULL));
else
{
if (flags_on == 0)
set_builtin ((WORD_LIST *)NULL);
else
set_or_show_attributes ((WORD_LIST *)NULL, flags_on, nodefs);
}
set_or_show_attributes ((WORD_LIST *)NULL, flags_on, nodefs);
fflush (stdout);
return (EXECUTION_SUCCESS);
return (sh_chkwrite (EXECUTION_SUCCESS));
}
if (pflag) /* declare -p [-afFirtx] name [name...] */
@@ -213,7 +210,7 @@ declare_internal (list, local_var)
any_failed++;
}
}
return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
return (sh_chkwrite (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS));
}
#define NEXT_VARIABLE() free (name); list = list->next; continue
@@ -335,8 +332,9 @@ declare_internal (list, local_var)
#endif /* DEBUGGER */
{
t = nodefs ? var->name
: named_function_string (name, function_cell (var), 1);
: named_function_string (name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL);
printf ("%s\n", t);
any_failed = sh_chkwrite (any_failed);
}
}
else /* declare -[fF] -[rx] name [name...] */
+1 -1
View File
@@ -208,7 +208,7 @@ A star (*) next to a name means that the command is disabled.\n\
blurb[width - 2] = '>'; /* indicate truncation */
blurb[width - 1] = '\0';
printf ("%s", blurb);
if ((i << 1) == num_shell_builtins)
if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins))
{
printf ("\n");
break;
+229
View File
@@ -0,0 +1,229 @@
This file is help.def, from which is created help.c.
It implements the builtin "help" in Bash.
Copyright (C) 1987-2006 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 2, 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; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
$PRODUCES help.c
$BUILTIN help
$FUNCTION help_builtin
$DEPENDS_ON HELP_BUILTIN
$SHORT_DOC help [-s] [pattern ...]
Display helpful information about builtin commands. If PATTERN is
specified, gives detailed help on all commands matching PATTERN,
otherwise a list of the builtins is printed. The -s option
restricts the output for each builtin command matching PATTERN to
a short usage synopsis.
$END
#include <config.h>
#if defined (HELP_BUILTIN)
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <errno.h>
#include <filecntl.h>
#include "../bashintl.h"
#include "../shell.h"
#include "../builtins.h"
#include "../pathexp.h"
#include "common.h"
#include "bashgetopt.h"
#include <glob/strmatch.h>
#include <glob/glob.h>
#ifndef errno
extern int errno;
#endif
static void show_builtin_command_help __P((void));
static void show_longdoc __P((int));
/* Print out a list of the known functions in the shell, and what they do.
If LIST is supplied, print out the list which matches for each pattern
specified. */
int
help_builtin (list)
WORD_LIST *list;
{
register int i;
char *pattern, *name;
int plen, match_found, sflag;
sflag = 0;
reset_internal_getopt ();
while ((i = internal_getopt (list, "s")) != -1)
{
switch (i)
{
case 's':
sflag = 1;
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (list == 0)
{
show_shell_version (0);
show_builtin_command_help ();
return (EXECUTION_SUCCESS);
}
/* We should consider making `help bash' do something. */
if (glob_pattern_p (list->word->word))
{
if (list->next)
printf (_("Shell commands matching keywords `"));
else
printf (_("Shell commands matching keyword `"));
print_word_list (list, ", ");
printf ("'\n\n");
}
for (match_found = 0, pattern = ""; list; list = list->next)
{
pattern = list->word->word;
plen = strlen (pattern);
for (i = 0; name = shell_builtins[i].name; i++)
{
QUIT;
if ((strncmp (pattern, name, plen) == 0) ||
(strmatch (pattern, name, FNMATCH_EXTFLAG) != FNM_NOMATCH))
{
printf ("%s: %s\n", name, shell_builtins[i].short_doc);
if (sflag == 0)
show_longdoc (i);
match_found++;
}
}
}
if (match_found == 0)
{
builtin_error (_("no help topics match `%s'. Try `help help' or `man -k %s' or `info %s'."), pattern, pattern, pattern);
return (EXECUTION_FAILURE);
}
fflush (stdout);
return (EXECUTION_SUCCESS);
}
/* By convention, enforced by mkbuiltins.c, if separate help files are being
used, the long_doc array contains one string -- the full pathname of the
help file for this builtin. */
static void
show_longdoc (i)
int i;
{
register int j;
char * const *doc;
int fd;
doc = shell_builtins[i].long_doc;
if (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL)
{
fd = open (doc[0], O_RDONLY);
if (fd == -1)
{
builtin_error (_("%s: cannot open: %s"), doc[0], strerror (errno));
return;
}
zcatfd (fd, 1, doc[0]);
close (fd);
}
else
for (j = 0; doc[j]; j++)
printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j]));
}
static void
show_builtin_command_help ()
{
int i, j;
int height, width;
char *t, blurb[128];
printf (
_("These shell commands are defined internally. Type `help' to see this list.\n\
Type `help name' to find out more about the function `name'.\n\
Use `info bash' to find out more about the shell in general.\n\
Use `man -k' or `info' to find out more about commands not in this list.\n\
\n\
A star (*) next to a name means that the command is disabled.\n\
\n"));
t = get_string_value ("COLUMNS");
width = (t && *t) ? atoi (t) : 80;
if (width <= 0)
width = 80;
width /= 2;
if (width > sizeof (blurb))
width = sizeof (blurb);
height = (num_shell_builtins + 1) / 2; /* number of rows */
for (i = 0; i < height; i++)
{
QUIT;
/* first column */
blurb[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*';
strncpy (blurb + 1, shell_builtins[i].short_doc, width - 2);
blurb[width - 2] = '>'; /* indicate truncation */
blurb[width - 1] = '\0';
printf ("%s", blurb);
if (((i << 1) >= num_shell_builtins)) /* || (i+height >= num_shell_builtins)) */
{
printf ("\n");
break;
}
/* two spaces */
for (j = strlen (blurb); j < width; j++)
putc (' ', stdout);
/* second column */
blurb[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*';
strncpy (blurb + 1, shell_builtins[i+height].short_doc, width - 3);
blurb[width - 3] = '>'; /* indicate truncation */
blurb[width - 2] = '\0';
printf ("%s\n", blurb);
}
}
#endif /* HELP_BUILTIN */
+5 -1
View File
@@ -148,6 +148,8 @@ extern int errno;
vbsize = 0; \
vbuf = 0; \
} \
else if (vbuf) \
vbuf[0] = 0; \
fflush (stdout); \
if (ferror (stdout)) \
{ \
@@ -228,6 +230,8 @@ printf_builtin (list)
{
vflag = 1;
vblen = 0;
if (vbuf)
vbuf[0] = 0;
}
else
{
@@ -835,7 +839,7 @@ vbadd (buf, blen)
if (blen == 1)
vbuf[vblen++] = buf[0];
else
else if (blen > 1)
{
FASTCOPY (buf, vbuf + vblen, blen);
vblen += blen;
+4 -2
View File
@@ -1,7 +1,7 @@
This file is printf.def, from which is created printf.c.
It implements the builtin "printf" in Bash.
Copyright (C) 1997-2006 Free Software Foundation, Inc.
Copyright (C) 1997-2007 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -228,6 +228,8 @@ printf_builtin (list)
{
vflag = 1;
vblen = 0;
if (vbuf)
vbuf[0] = 0;
}
else
{
@@ -835,7 +837,7 @@ vbadd (buf, blen)
if (blen == 1)
vbuf[vblen++] = buf[0];
else
else if (blen > 1)
{
FASTCOPY (buf, vbuf + vblen, blen);
vblen += blen;
+62 -2
View File
@@ -94,6 +94,9 @@ static void set_eol_delim __P((int));
static void reset_eol_delim __P((char *));
#endif
static SHELL_VAR *bind_read_variable __P((char *, char *));
#if defined (HANDLE_MULTIBYTE)
static int read_mbchar __P((int, char *, int, int, int));
#endif
static sighandler sigalrm __P((int));
static void reset_alarm __P((void));
@@ -441,7 +444,7 @@ read_builtin (list)
}
#endif
if (i + 2 >= size)
if (i + 4 >= size) /* XXX was i + 2; use i + 4 for multibyte/read_mbchar */
{
input_string = (char *)xrealloc (input_string, size += 128);
remove_unwind_protect ();
@@ -456,7 +459,7 @@ read_builtin (list)
if (c == '\n')
{
i--; /* back up over the CTLESC */
if (interactive && raw == 0)
if (interactive && input_is_tty && raw == 0)
print_ps2 = 1;
}
else
@@ -487,6 +490,15 @@ read_builtin (list)
add_char:
input_string[i++] = c;
#if defined (HANDLE_MULTIBYTE)
if (nchars > 0 && MB_CUR_MAX > 1)
{
input_string[i] = '\0'; /* for simplicity and debugging */
i += read_mbchar (fd, input_string, i, c, unbuffered_read);
}
#endif
nr++;
if (nchars > 0 && nr >= nchars)
@@ -721,6 +733,54 @@ bind_read_variable (name, value)
#endif /* !ARRAY_VARS */
}
#if defined (HANDLE_MULTIBYTE)
static int
read_mbchar (fd, string, ind, ch, unbuffered)
int fd;
char *string;
int ind, ch, unbuffered;
{
char mbchar[MB_LEN_MAX + 1];
int i, n, r;
char c;
size_t ret;
mbstate_t ps, ps_back;
wchar_t wc;
memset (&ps, '\0', sizeof (mbstate_t));
memset (&ps_back, '\0', sizeof (mbstate_t));
mbchar[0] = ch;
i = 1;
for (n = 0; n <= MB_LEN_MAX; n++)
{
ps_back = ps;
ret = mbrtowc (&wc, mbchar, i, &ps);
if (ret == (size_t)-2)
{
ps = ps_back;
if (unbuffered)
r = zread (fd, &c, 1);
else
r = zreadc (fd, &c);
if (r < 0)
goto mbchar_return;
mbchar[i++] = c;
continue;
}
else if (ret == (size_t)-1 || ret == (size_t)0 || ret > (size_t)0)
break;
}
mbchar_return:
if (i > 1) /* read a multibyte char */
/* mbchar[0] is already string[ind-1] */
for (r = 1; r < i; r++)
string[ind+r-1] = mbchar[r];
return i - 1;
}
#endif
#if defined (READLINE)
static rl_completion_func_t *old_attempted_completion_function = 0;
+5 -5
View File
@@ -128,7 +128,7 @@ read_builtin (list)
{
register char *varname;
int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc;
int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
int raw, edit, nchars, silent, have_timeout, fd;
unsigned int tmout;
intmax_t intval;
@@ -263,8 +263,8 @@ read_builtin (list)
ifs_chars = getifs ();
if (ifs_chars == 0) /* XXX - shouldn't happen */
ifs_chars = "";
for (skip_ctlesc = 0, e = ifs_chars; *e; e++)
skip_ctlesc |= *e == CTLESC;
for (skip_ctlesc = skip_ctlnul = 0, e = ifs_chars; *e; e++)
skip_ctlesc |= *e == CTLESC, skip_ctlnul |= *e == CTLNUL;
input_string = (char *)xmalloc (size = 112); /* XXX was 128 */
@@ -456,7 +456,7 @@ read_builtin (list)
if (c == '\n')
{
i--; /* back up over the CTLESC */
if (interactive && raw == 0)
if (interactive && input_is_tty && raw == 0)
print_ps2 = 1;
}
else
@@ -479,7 +479,7 @@ read_builtin (list)
if ((unsigned char)c == delim)
break;
if ((skip_ctlesc == 0 && c == CTLESC) || c == CTLNUL)
if ((skip_ctlesc == 0 && c == CTLESC) || (skip_ctlnul == 0 && c == CTLNUL))
{
saw_escape++;
input_string[i++] = CTLESC;
+66 -6
View File
@@ -94,6 +94,9 @@ static void set_eol_delim __P((int));
static void reset_eol_delim __P((char *));
#endif
static SHELL_VAR *bind_read_variable __P((char *, char *));
#if defined (HANDLE_MULTIBYTE)
static int read_mbchar __P((int, char *, int, int, int));
#endif
static sighandler sigalrm __P((int));
static void reset_alarm __P((void));
@@ -128,7 +131,7 @@ read_builtin (list)
{
register char *varname;
int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc;
int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
int raw, edit, nchars, silent, have_timeout, fd;
unsigned int tmout;
intmax_t intval;
@@ -263,8 +266,8 @@ read_builtin (list)
ifs_chars = getifs ();
if (ifs_chars == 0) /* XXX - shouldn't happen */
ifs_chars = "";
for (skip_ctlesc = 0, e = ifs_chars; *e; e++)
skip_ctlesc |= *e == CTLESC;
for (skip_ctlesc = skip_ctlnul = 0, e = ifs_chars; *e; e++)
skip_ctlesc |= *e == CTLESC, skip_ctlnul |= *e == CTLNUL;
input_string = (char *)xmalloc (size = 112); /* XXX was 128 */
@@ -441,7 +444,7 @@ read_builtin (list)
}
#endif
if (i + 2 >= size)
if (i + 4 >= size) /* XXX was i + 2; use i + 4 for multibyte/read_mbchar */
{
input_string = (char *)xrealloc (input_string, size += 128);
remove_unwind_protect ();
@@ -456,7 +459,7 @@ read_builtin (list)
if (c == '\n')
{
i--; /* back up over the CTLESC */
if (interactive && raw == 0)
if (interactive && input_is_tty && raw == 0)
print_ps2 = 1;
}
else
@@ -479,7 +482,7 @@ read_builtin (list)
if ((unsigned char)c == delim)
break;
if ((skip_ctlesc == 0 && c == CTLESC) || c == CTLNUL)
if ((skip_ctlesc == 0 && c == CTLESC) || (skip_ctlnul == 0 && c == CTLNUL))
{
saw_escape++;
input_string[i++] = CTLESC;
@@ -487,6 +490,15 @@ read_builtin (list)
add_char:
input_string[i++] = c;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1)
{
input_string[i] = '\0'; /* for simplicity and debugging */
i += read_mbchar (fd, input_string, i, c, unbuffered_read);
}
#endif
nr++;
if (nchars > 0 && nr >= nchars)
@@ -721,6 +733,54 @@ bind_read_variable (name, value)
#endif /* !ARRAY_VARS */
}
#if defined (HANDLE_MULTIBYTE)
static int
read_mbchar (fd, string, ind, ch, unbuffered)
int fd;
char *string;
int ind, ch, unbuffered;
{
char mbchar[MB_LEN_MAX + 1];
int i, n, r;
char c;
size_t ret;
mbstate_t ps, ps_back;
wchar_t wc;
memset (&ps, '\0', sizeof (mbstate_t));
memset (&ps_back, '\0', sizeof (mbstate_t));
mbchar[0] = ch;
i = 1;
for (n = 0; n <= MB_LEN_MAX; n++)
{
ps_back = ps;
ret = mbrtowc (&wc, mbchar, i, &ps);
if (ret == (size_t)-2)
{
ps = ps_back;
if (unbuffered)
r = zread (fd, &c, 1);
else
r = zreadc (fd, &c);
if (r < 0)
goto mbchar_return;
mbchar[i++] = c;
continue;
}
else if (ret == (size_t)-1 || ret == (size_t)0 || ret > (size_t)0)
break;
}
mbchar_return:
if (i > 1) /* read a multibyte char */
/* mbchar[0] is already string[ind-1] */
for (r = 1; r < i; r++)
string[ind+r-1] = mbchar[r];
return i - 1;
}
#endif
#if defined (READLINE)
static rl_completion_func_t *old_attempted_completion_function = 0;
+2 -2
View File
@@ -340,7 +340,7 @@ show_var_attributes (var, pattr, nodefs)
reused as input to recreate the current state. */
if (function_p (var) && nodefs == 0 && (pattr == 0 || posixly_correct == 0))
{
printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL));
nodefs++;
if (pattr == 0 && i == 1 && flags[0] == 'f')
return 0; /* don't print `declare -f name' */
@@ -363,7 +363,7 @@ show_var_attributes (var, pattr, nodefs)
if (nodefs || (function_p (var) && pattr != 0 && posixly_correct))
printf ("%s\n", var->name);
else if (function_p (var))
printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL));
else if (invisible_p (var))
printf ("%s\n", var->name);
else
+9 -5
View File
@@ -1,7 +1,7 @@
This file is setattr.def, from which is created setattr.c.
It implements the builtins "export" and "readonly", in Bash.
Copyright (C) 1987-2006 Free Software Foundation, Inc.
Copyright (C) 1987-2007 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -52,7 +52,7 @@ extern int declare_builtin __P((WORD_LIST *));
$BUILTIN export
$FUNCTION export_builtin
$SHORT_DOC export [-nf] [name[=value] ...] or export -p
$SHORT_DOC export [-fn] [name[=value] ...] or export -p
NAMEs are marked for automatic export to the environment of
subsequently executed commands. If the -f option is given,
the NAMEs refer to functions. If no NAMEs are given, or if `-p'
@@ -268,7 +268,11 @@ set_or_show_attributes (list, attribute, nodefs)
continue;
#endif
if ((var->attributes & attribute))
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
if (any_failed = sh_chkwrite (any_failed))
break;
}
}
free (variable_list);
}
@@ -336,7 +340,7 @@ show_var_attributes (var, pattr, nodefs)
reused as input to recreate the current state. */
if (function_p (var) && nodefs == 0 && (pattr == 0 || posixly_correct == 0))
{
printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE));
nodefs++;
if (pattr == 0 && i == 1 && flags[0] == 'f')
return 0; /* don't print `declare -f name' */
@@ -359,7 +363,7 @@ show_var_attributes (var, pattr, nodefs)
if (nodefs || (function_p (var) && pattr != 0 && posixly_correct))
printf ("%s\n", var->name);
else if (function_p (var))
printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE));
else if (invisible_p (var))
printf ("%s\n", var->name);
else
+2 -6
View File
@@ -1,7 +1,7 @@
This file is type.def, from which is created type.c.
It implements the builtin "type" in Bash.
Copyright (C) 1987-2002 Free Software Foundation, Inc.
Copyright (C) 1987-2007 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -266,18 +266,14 @@ describe_command (command, dflags)
puts ("function");
else if (dflags & CDESC_SHORTDESC)
{
#define PRETTY_PRINT_FUNC 1
char *result;
printf (_("%s is a function\n"), command);
/* We're blowing away THE_PRINTED_COMMAND here... */
result = named_function_string (command,
(COMMAND *) function_cell (func),
PRETTY_PRINT_FUNC);
result = named_function_string (command, function_cell (func), FUNC_MULTILINE|FUNC_EXTERNAL);
printf ("%s\n", result);
#undef PRETTY_PRINT_FUNC
}
else if (dflags & CDESC_REUSABLE)
printf ("%s\n", command);
+5 -10
View File
@@ -1,7 +1,7 @@
This file is type.def, from which is created type.c.
It implements the builtin "type" in Bash.
Copyright (C) 1987-2002 Free Software Foundation, Inc.
Copyright (C) 1987-2007 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -185,9 +185,8 @@ type_builtin (list)
list = list->next;
}
fflush (stdout);
return ((successful_finds != 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
opt = (successful_finds != 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE;
return (sh_chkwrite (opt));
}
/*
@@ -267,18 +266,14 @@ describe_command (command, dflags)
puts ("function");
else if (dflags & CDESC_SHORTDESC)
{
#define PRETTY_PRINT_FUNC 1
char *result;
printf (_("%s is a function\n"), command);
/* We're blowing away THE_PRINTED_COMMAND here... */
result = named_function_string (command,
(COMMAND *) function_cell (func),
PRETTY_PRINT_FUNC);
result = named_function_string (command, function_cell (func), FUNC_MULTILINE);
printf ("%s\n", result);
#undef PRETTY_PRINT_FUNC
}
else if (dflags & CDESC_REUSABLE)
printf ("%s\n", command);
@@ -390,7 +385,7 @@ describe_command (command, dflags)
if (dflags & CDESC_TYPE)
puts ("file");
else if (dflags & CDESC_SHORTDESC)
printf ("%s is %s\n", command, full_path);
printf (_("%s is %s\n"), command, full_path);
else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY))
printf ("%s\n", full_path);
+47
View File
@@ -0,0 +1,47 @@
*** ../bash-3.2-patched/lib/readline/display.c Fri Apr 20 15:19:04 2007
--- lib/readline/display.c Thu May 24 14:13:57 2007
***************
*** 1518,1528 ****
{
/* Non-zero if we're increasing the number of lines. */
int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
/* Sometimes it is cheaper to print the characters rather than
use the terminal's capabilities. If we're growing the number
of lines, make sure we actually cause the new line to wrap
around on auto-wrapping terminals. */
! if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
{
/* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
_rl_horizontal_scroll_mode == 1, inserting the characters with
--- 1544,1574 ----
{
/* Non-zero if we're increasing the number of lines. */
int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
+ /* If col_lendiff is > 0, implying that the new string takes up more
+ screen real estate than the old, but lendiff is < 0, meaning that it
+ takes fewer bytes, we need to just output the characters starting
+ from the first difference. These will overwrite what is on the
+ display, so there's no reason to do a smart update. This can really
+ only happen in a multibyte environment. */
+ if (lendiff < 0)
+ {
+ _rl_output_some_chars (nfd, temp);
+ _rl_last_c_pos += _rl_col_width (nfd, 0, temp);
+ /* If nfd begins before any invisible characters in the prompt,
+ adjust _rl_last_c_pos to account for wrap_offset and set
+ cpos_adjusted to let the caller know. */
+ if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
+ {
+ _rl_last_c_pos -= wrap_offset;
+ cpos_adjusted = 1;
+ }
+ return;
+ }
/* Sometimes it is cheaper to print the characters rather than
use the terminal's capabilities. If we're growing the number
of lines, make sure we actually cause the new line to wrap
around on auto-wrapping terminals. */
! else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
{
/* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
_rl_horizontal_scroll_mode == 1, inserting the characters with
+1 -1
View File
@@ -108,7 +108,7 @@ get_name_for_error ()
if (bash_source_v && array_p (bash_source_v) &&
(bash_source_a = array_cell (bash_source_v)))
name = array_reference (bash_source_a, 0);
if (name == 0)
if (name == 0 || *name == '\0') /* XXX - was just name == 0 */
#endif
name = dollar_vars[0];
}
+3 -3
View File
@@ -59,7 +59,7 @@ extern int give_terminal_to __P((pid_t, int));
#endif /* JOB_CONTROL */
#if defined (ARRAY_VARS)
extern char *bash_badsub_errmsg;
extern const char * const bash_badsub_errmsg;
#endif
static void error_prolog __P((int));
@@ -70,7 +70,7 @@ static void error_prolog __P((int));
#define MAINTAINER "bash-maintainers@gnu.org"
#endif
char *the_current_maintainer = MAINTAINER;
const char * const the_current_maintainer = MAINTAINER;
int gnu_error_format = 0;
@@ -399,7 +399,7 @@ trace (format, va_alist)
/* **************************************************************** */
static char *cmd_error_table[] = {
static const char * const cmd_error_table[] = {
N_("unknown command error"), /* CMDERR_DEFAULT */
N_("bad command type"), /* CMDERR_BADTYPE */
N_("bad connector"), /* CMDERR_BADCONN */
+3
View File
@@ -30,6 +30,9 @@
extern intmax_t evalexp __P((char *, int *));
/* Functions from print_cmd.c. */
#define FUNC_MULTILINE 0x01
#define FUNC_EXTERNAL 0x02
extern char *make_command_string __P((COMMAND *));
extern char *named_function_string __P((char *, COMMAND *, int));
+399
View File
@@ -0,0 +1,399 @@
/* externs.h -- extern function declarations which do not appear in their
own header file. */
/* Copyright (C) 1993-2005 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 2, 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; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
/* Make sure that this is included *after* config.h! */
#if !defined (_EXTERNS_H_)
# define _EXTERNS_H_
#include "stdc.h"
/* Functions from expr.c. */
extern intmax_t evalexp __P((char *, int *));
/* Functions from print_cmd.c. */
extern char *make_command_string __P((COMMAND *));
extern char *named_function_string __P((char *, COMMAND *, int));
extern void print_command __P((COMMAND *));
extern void print_simple_command __P((SIMPLE_COM *));
extern void print_word_list __P((WORD_LIST *, char *));
/* debugger support */
extern void print_for_command_head __P((FOR_COM *));
#if defined (SELECT_COMMAND)
extern void print_select_command_head __P((SELECT_COM *));
#endif
extern void print_case_command_head __P((CASE_COM *));
#if defined (DPAREN_ARITHMETIC)
extern void print_arith_command __P((WORD_LIST *));
#endif
#if defined (COND_COMMAND)
extern void print_cond_command __P((COND_COM *));
#endif
/* set -x support */
extern char *indirection_level_string __P((void));
extern void xtrace_print_assignment __P((char *, char *, int, int));
extern void xtrace_print_word_list __P((WORD_LIST *, int));
extern void xtrace_print_for_command_head __P((FOR_COM *));
#if defined (SELECT_COMMAND)
extern void xtrace_print_select_command_head __P((SELECT_COM *));
#endif
extern void xtrace_print_case_command_head __P((CASE_COM *));
#if defined (DPAREN_ARITHMETIC)
extern void xtrace_print_arith_cmd __P((WORD_LIST *));
#endif
#if defined (COND_COMMAND)
extern void xtrace_print_cond_term __P((int, int, WORD_DESC *, char *, char *));
#endif
/* Functions from shell.c. */
extern void exit_shell __P((int)) __attribute__((__noreturn__));
extern void sh_exit __P((int)) __attribute__((__noreturn__));
extern void disable_priv_mode __P((void));
extern void unbind_args __P((void));
#if defined (RESTRICTED_SHELL)
extern int shell_is_restricted __P((char *));
extern int maybe_make_restricted __P((char *));
#endif
extern void unset_bash_input __P((int));
extern void get_current_user_info __P((void));
/* Functions from eval.c. */
extern int reader_loop __P((void));
extern int parse_command __P((void));
extern int read_command __P((void));
/* Functions from braces.c. */
#if defined (BRACE_EXPANSION)
extern char **brace_expand __P((char *));
#endif
/* Miscellaneous functions from parse.y */
extern int yyparse __P((void));
extern int return_EOF __P((void));
extern void reset_parser __P((void));
extern WORD_LIST *parse_string_to_word_list __P((char *, int, const char *));
extern void free_pushed_string_input __P((void));
extern char *decode_prompt_string __P((char *));
extern int get_current_prompt_level __P((void));
extern void set_current_prompt_level __P((int));
#if defined (HISTORY)
extern char *history_delimiting_chars __P((void));
#endif
/* Declarations for functions defined in locale.c */
extern void set_default_locale __P((void));
extern void set_default_locale_vars __P((void));
extern int set_locale_var __P((char *, char *));
extern int set_lang __P((char *, char *));
extern void set_default_lang __P((void));
extern char *get_locale_var __P((char *));
extern char *localetrans __P((char *, int, int *));
extern char *mk_msgstr __P((char *, int *));
extern char *localeexpand __P((char *, int, int, int, int *));
/* Declarations for functions defined in list.c. */
extern void list_walk __P((GENERIC_LIST *, sh_glist_func_t *));
extern void wlist_walk __P((WORD_LIST *, sh_icpfunc_t *));
extern GENERIC_LIST *list_reverse ();
extern int list_length ();
extern GENERIC_LIST *list_append ();
extern GENERIC_LIST *list_remove ();
/* Declarations for functions defined in stringlib.c */
extern int find_string_in_alist __P((char *, STRING_INT_ALIST *, int));
extern char *find_token_in_alist __P((int, STRING_INT_ALIST *, int));
extern int find_index_in_alist __P((char *, STRING_INT_ALIST *, int));
extern char *substring __P((char *, int, int));
extern char *strsub __P((char *, char *, char *, int));
extern char *strcreplace __P((char *, int, char *, int));
extern void strip_leading __P((char *));
extern void strip_trailing __P((char *, int, int));
extern void xbcopy __P((char *, char *, int));
/* Functions from version.c. */
extern char *shell_version_string __P((void));
extern void show_shell_version __P((int));
/* Functions from the bash library, lib/sh/libsh.a. These should really
go into a separate include file. */
/* declarations for functions defined in lib/sh/clktck.c */
extern long get_clk_tck __P((void));
/* declarations for functions defined in lib/sh/clock.c */
extern void clock_t_to_secs ();
extern void print_clock_t ();
/* Declarations for functions defined in lib/sh/fmtulong.c */
#define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */
#define FL_ADDBASE 0x02 /* add base# prefix to converted value */
#define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */
#define FL_UNSIGNED 0x08 /* don't add any sign */
extern char *fmtulong __P((unsigned long int, int, char *, size_t, int));
/* Declarations for functions defined in lib/sh/fmtulong.c */
#if defined (HAVE_LONG_LONG)
extern char *fmtullong __P((unsigned long long int, int, char *, size_t, int));
#endif
/* Declarations for functions defined in lib/sh/fmtumax.c */
extern char *fmtumax __P((uintmax_t, int, char *, size_t, int));
/* Declarations for functions defined in lib/sh/getcwd.c */
#if !defined (HAVE_GETCWD)
extern char *getcwd __P((char *, size_t));
#endif
/* Declarations for functions defined in lib/sh/itos.c */
extern char *inttostr __P((intmax_t, char *, size_t));
extern char *itos __P((intmax_t));
extern char *uinttostr __P((uintmax_t, char *, size_t));
extern char *uitos __P((uintmax_t));
/* declarations for functions defined in lib/sh/makepath.c */
#define MP_DOTILDE 0x01
#define MP_DOCWD 0x02
#define MP_RMDOT 0x04
extern char *sh_makepath __P((const char *, const char *, int));
/* declarations for functions defined in lib/sh/netconn.c */
extern int isnetconn __P((int));
/* declarations for functions defined in lib/sh/netopen.c */
extern int netopen __P((char *));
/* Declarations for functions defined in lib/sh/oslib.c */
#if !defined (HAVE_DUP2) || defined (DUP2_BROKEN)
extern int dup2 __P((int, int));
#endif
#if !defined (HAVE_GETDTABLESIZE)
extern int getdtablesize __P((void));
#endif /* !HAVE_GETDTABLESIZE */
#if !defined (HAVE_GETHOSTNAME)
extern int gethostname __P((char *, int));
#endif /* !HAVE_GETHOSTNAME */
extern int getmaxgroups __P((void));
extern long getmaxchild __P((void));
/* declarations for functions defined in lib/sh/pathcanon.c */
#define PATH_CHECKDOTDOT 0x0001
#define PATH_CHECKEXISTS 0x0002
#define PATH_HARDPATH 0x0004
#define PATH_NOALLOC 0x0008
extern char *sh_canonpath __P((char *, int));
/* declarations for functions defined in lib/sh/pathphys.c */
extern char *sh_physpath __P((char *, int));
extern char *sh_realpath __P((const char *, char *));
/* declarations for functions defined in lib/sh/setlinebuf.c */
#ifdef NEED_SH_SETLINEBUF_DECL
extern int sh_setlinebuf __P((FILE *));
#endif
/* declarations for functions defined in lib/sh/shaccess.c */
extern int sh_eaccess __P((char *, int));
/* declarations for functions defined in lib/sh/shmatch.c */
extern int sh_regmatch __P((const char *, const char *, int));
/* defines for flags argument to sh_regmatch. */
#define SHMAT_SUBEXP 0x001 /* save subexpressions in SH_REMATCH */
#define SHMAT_PWARN 0x002 /* print a warning message on invalid regexp */
/* declarations for functions defined in lib/sh/shquote.c */
extern char *sh_single_quote __P((char *));
extern char *sh_double_quote __P((char *));
extern char *sh_mkdoublequoted __P((const char *, int, int));
extern char *sh_un_double_quote __P((char *));
extern char *sh_backslash_quote __P((char *));
extern char *sh_backslash_quote_for_double_quotes __P((char *));
extern int sh_contains_shell_metas __P((char *));
/* declarations for functions defined in lib/sh/spell.c */
extern int spname __P((char *, char *));
/* declarations for functions defined in lib/sh/strcasecmp.c */
#if !defined (HAVE_STRCASECMP)
extern int strncasecmp __P((const char *, const char *, int));
extern int strcasecmp __P((const char *, const char *));
#endif /* HAVE_STRCASECMP */
/* declarations for functions defined in lib/sh/strerror.c */
#if !defined (HAVE_STRERROR) && !defined (strerror)
extern char *strerror __P((int));
#endif
/* declarations for functions defined in lib/sh/strftime.c */
#if !defined (HAVE_STRFTIME) && defined (NEED_STRFTIME_DECL)
extern size_t strftime __P((char *, size_t, const char *, const struct tm *));
#endif
/* declarations for functions defined in lib/sh/strindex.c */
extern char *strindex __P((const char *, const char *));
/* declarations for functions and structures defined in lib/sh/stringlist.c */
/* This is a general-purpose argv-style array struct. */
typedef struct _list_of_strings {
char **list;
int list_size;
int list_len;
} STRINGLIST;
typedef int sh_strlist_map_func_t __P((char *));
extern STRINGLIST *strlist_create __P((int));
extern STRINGLIST *strlist_resize __P((STRINGLIST *, int));
extern void strlist_flush __P((STRINGLIST *));
extern void strlist_dispose __P((STRINGLIST *));
extern int strlist_remove __P((STRINGLIST *, char *));
extern STRINGLIST *strlist_copy __P((STRINGLIST *));
extern STRINGLIST *strlist_merge __P((STRINGLIST *, STRINGLIST *));
extern STRINGLIST *strlist_append __P((STRINGLIST *, STRINGLIST *));
extern STRINGLIST *strlist_prefix_suffix __P((STRINGLIST *, char *, char *));
extern void strlist_print __P((STRINGLIST *, char *));
extern void strlist_walk __P((STRINGLIST *, sh_strlist_map_func_t *));
extern void strlist_sort __P((STRINGLIST *));
/* declarations for functions defined in lib/sh/stringvec.c */
extern char **strvec_create __P((int));
extern char **strvec_resize __P((char **, int));
extern void strvec_flush __P((char **));
extern void strvec_dispose __P((char **));
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_strcmp __P((char **, char **));
extern void strvec_sort __P((char **));
extern char **strvec_from_word_list __P((WORD_LIST *, int, int, int *));
extern WORD_LIST *strvec_to_word_list __P((char **, int, int));
/* declarations for functions defined in lib/sh/strnlen.c */
#if !defined (HAVE_STRNLEN)
extern size_t strnlen __P((const char *, size_t));
#endif
/* declarations for functions defined in lib/sh/strpbrk.c */
#if !defined (HAVE_STRPBRK)
extern char *strpbrk __P((const char *, const char *));
#endif
/* declarations for functions defined in lib/sh/strtod.c */
#if !defined (HAVE_STRTOD)
extern double strtod __P((const char *, char **));
#endif
/* declarations for functions defined in lib/sh/strtol.c */
#if !HAVE_DECL_STRTOL
extern long strtol __P((const char *, char **, int));
#endif
/* declarations for functions defined in lib/sh/strtoll.c */
#if defined (HAVE_LONG_LONG) && !HAVE_DECL_STRTOLL
extern long long strtoll __P((const char *, char **, int));
#endif
/* declarations for functions defined in lib/sh/strtoul.c */
#if !HAVE_DECL_STRTOUL
extern unsigned long strtoul __P((const char *, char **, int));
#endif
/* declarations for functions defined in lib/sh/strtoull.c */
#if defined (HAVE_LONG_LONG) && !HAVE_DECL_STRTOULL
extern unsigned long long strtoull __P((const char *, char **, int));
#endif
/* declarations for functions defined in lib/sh/strimax.c */
#if !HAVE_DECL_STRTOIMAX
extern intmax_t strtoimax __P((const char *, char **, int));
#endif
/* declarations for functions defined in lib/sh/strumax.c */
#if !HAVE_DECL_STRTOUMAX
extern uintmax_t strtoumax __P((const char *, char **, int));
#endif
/* declarations for functions defined in lib/sh/strtrans.c */
extern char *ansicstr __P((char *, int, int, int *, int *));
extern char *ansic_quote __P((char *, int, int *));
extern int ansic_shouldquote __P((const char *));
extern char *ansiexpand __P((char *, int, int, int *));
/* declarations for functions defined in lib/sh/timeval.c. No prototypes
so we don't have to count on having a definition of struct timeval in
scope when this file is included. */
extern void timeval_to_secs ();
extern void print_timeval ();
/* declarations for functions defined in lib/sh/tmpfile.c */
#define MT_USETMPDIR 0x0001
#define MT_READWRITE 0x0002
#define MT_USERANDOM 0x0004
extern char *sh_mktmpname __P((char *, int));
extern int sh_mktmpfd __P((char *, int, char **));
/* extern FILE *sh_mktmpfp __P((char *, int, char **)); */
/* declarations for functions defined in lib/sh/winsize.c */
extern void get_new_window_size __P((int, int *, int *));
/* declarations for functions defined in lib/sh/xstrchr.c */
#undef xstrchr
extern char *xstrchr __P((const char *, int));
/* declarations for functions defined in lib/sh/zcatfd.c */
extern int zcatfd __P((int, int, char *));
/* declarations for functions defined in lib/sh/zmapfd.c */
extern int zmapfd __P((int, char **, char *));
/* declarations for functions defined in lib/sh/zread.c */
extern ssize_t zread __P((int, char *, size_t));
extern ssize_t zreadintr __P((int, char *, size_t));
extern ssize_t zreadc __P((int, char *));
extern void zreset __P((void));
extern void zsyncfd __P((int));
/* declarations for functions defined in lib/sh/zwrite.c */
extern int zwrite __P((int, char *, size_t));
#endif /* _EXTERNS_H_ */
+65
View File
@@ -0,0 +1,65 @@
*** ../bash-20070510/jobs.c Thu Mar 8 16:05:50 2007
--- jobs.c Fri May 18 11:40:14 2007
***************
*** 784,792 ****
{
old = js.j_firstj++;
while (js.j_firstj != old)
{
if (js.j_firstj >= js.j_jobslots)
js.j_firstj = 0;
! if (jobs[js.j_firstj])
break;
js.j_firstj++;
--- 784,794 ----
{
old = js.j_firstj++;
+ if (old >= js.j_jobslots)
+ old = js.j_jobslots - 1;
while (js.j_firstj != old)
{
if (js.j_firstj >= js.j_jobslots)
js.j_firstj = 0;
! if (jobs[js.j_firstj] || js.j_firstj == old) /* needed if old == 0 */
break;
js.j_firstj++;
***************
*** 798,806 ****
{
old = js.j_lastj--;
while (js.j_lastj != old)
{
if (js.j_lastj < 0)
js.j_lastj = js.j_jobslots - 1;
! if (jobs[js.j_lastj])
break;
js.j_lastj--;
--- 800,810 ----
{
old = js.j_lastj--;
+ if (old < 0)
+ old = 0;
while (js.j_lastj != old)
{
if (js.j_lastj < 0)
js.j_lastj = js.j_jobslots - 1;
! if (jobs[js.j_lastj] || js.j_lastj == old) /* needed if old == js.j_jobslots */
break;
js.j_lastj--;
***************
*** 964,968 ****
realloc_jobs_list ();
! return (js.j_lastj ? js.j_lastj + 1 : 0);
}
--- 975,983 ----
realloc_jobs_list ();
! #ifdef DEBUG
! itrace("compact_jobs_list: returning %d", (js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
! #endif
!
! return ((js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
}
+5 -1
View File
@@ -974,7 +974,10 @@ compact_jobs_list (flags)
reap_dead_jobs ();
realloc_jobs_list ();
itrace("compact_jobs_list: returning %d", (js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
#ifdef DEBUG
itrace("compact_jobs_list: returning %d", (js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
#endif
return ((js.j_lastj || jobs[js.j_lastj]) ? js.j_lastj + 1 : 0);
}
@@ -3554,6 +3557,7 @@ initialize_job_control (force)
setpgid (0, original_pgrp);
shell_pgrp = original_pgrp;
job_control = 0;
internal_error ("cannot set terminal pgrp to %d: %s", shell_pgrp, strerror (errno));
}
}
}
+21 -1
View File
@@ -1544,11 +1544,31 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
{
/* Non-zero if we're increasing the number of lines. */
int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
/* If col_lendiff is > 0, implying that the new string takes up more
screen real estate than the old, but lendiff is < 0, meaning that it
takes fewer bytes, we need to just output the characters starting
from the first difference. These will overwrite what is on the
display, so there's no reason to do a smart update. This can really
only happen in a multibyte environment. */
if (lendiff < 0)
{
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += _rl_col_width (nfd, 0, temp);
/* If nfd begins before any invisible characters in the prompt,
adjust _rl_last_c_pos to account for wrap_offset and set
cpos_adjusted to let the caller know. */
if (current_line == 0 && wrap_offset && ((nfd - new) <= prompt_last_invisible))
{
_rl_last_c_pos -= wrap_offset;
cpos_adjusted = 1;
}
return;
}
/* Sometimes it is cheaper to print the characters rather than
use the terminal's capabilities. If we're growing the number
of lines, make sure we actually cause the new line to wrap
around on auto-wrapping terminals. */
if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
{
/* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
_rl_horizontal_scroll_mode == 1, inserting the characters with
+17 -18
View File
@@ -1317,9 +1317,6 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
}
_rl_trace("update_line: old = %p \"%s\"", old, old);
_rl_trace("update_line: new = %p \"%s\"", new, new);
/* Find first difference. */
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
@@ -1356,8 +1353,6 @@ _rl_trace("update_line: new = %p \"%s\"", new, new);
}
}
}
_rl_trace("update_line: ofd = %p \"%s\"", ofd, ofd);
_rl_trace("update_line: nfd = %p \"%s\"", nfd, nfd);
}
else
#endif
@@ -1372,9 +1367,6 @@ _rl_trace("update_line: nfd = %p \"%s\"", nfd, nfd);
for (od = ofd - old, oe = ofd; od < omax && *oe; oe++, od++);
for (nd = nfd - new, ne = nfd; nd < nmax && *ne; ne++, nd++);
_rl_trace("update_line: oe = %p \"%s\"", oe, oe);
_rl_trace("update_line: ne = %p \"%s\"", ne, ne);
/* If no difference, continue to next line. */
if (ofd == oe && nfd == ne)
return;
@@ -1453,9 +1445,6 @@ _rl_trace("update_line: ne = %p \"%s\"", ne, ne);
}
}
_rl_trace("update_line: ols = %p \"%s\"", ols, ols);
_rl_trace("update_line: nls = %p \"%s\"", nls, nls);
/* count of invisible characters in the current invisible line. */
current_invis_chars = W_OFFSET (current_line, wrap_offset);
if (_rl_last_v_pos != current_line)
@@ -1488,18 +1477,18 @@ _rl_trace("update_line: nls = %p \"%s\"", nls, nls);
#else
tputs (_rl_term_cr, 1, _rl_output_character_function);
#endif
_rl_trace("update_line: redrawing prompt");
if (modmark)
_rl_output_some_chars ("*", 1);
_rl_output_some_chars (local_prompt, lendiff);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
/* We take wrap_offset into account here so we can pass correct
information to _rl_move_cursor_relative. */
_rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset;
_rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset + modmark;
cpos_adjusted = 1;
}
else
_rl_last_c_pos = lendiff;
_rl_trace("update_line: redrawing prompt: _rl_last_c_pos = %d", _rl_last_c_pos);
_rl_last_c_pos = lendiff + modmark;
}
/* When this function returns, _rl_last_c_pos is correct, and an absolute
@@ -1526,7 +1515,6 @@ _rl_trace("update_line: redrawing prompt: _rl_last_c_pos = %d", _rl_last_c_pos);
else
col_lendiff = lendiff;
_rl_trace("update_line: lendiff = %d col_lendiff = %d", lendiff, col_lendiff);
/* If we are changing the number of invisible characters in a line, and
the spot of first difference is before the end of the invisible chars,
lendiff needs to be adjusted. */
@@ -1545,7 +1533,6 @@ _rl_trace("update_line: lendiff = %d col_lendiff = %d", lendiff, col_lendiff);
}
}
_rl_trace("update_line: after adjustment: lendiff = %d col_lendiff = %d", lendiff, col_lendiff);
/* Insert (diff (len (old), len (new)) ch. */
temp = ne - nfd;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
@@ -1557,11 +1544,23 @@ _rl_trace("update_line: after adjustment: lendiff = %d col_lendiff = %d", lendif
{
/* Non-zero if we're increasing the number of lines. */
int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin;
/* If col_lendiff is > 0, implying that the new string takes up more
screen real estate than the old, but lendiff is < 0, meaning that it
takes fewer bytes, we need to just output the characters starting
from the first difference. These will overwrite what is on the
display, so there's no reason to do a smart update. This can really
only happen in a multibyte environment. */
if (lendiff < 0)
{
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += col_temp;
return;
}
/* Sometimes it is cheaper to print the characters rather than
use the terminal's capabilities. If we're growing the number
of lines, make sure we actually cause the new line to wrap
around on auto-wrapping terminals. */
if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
else if (_rl_terminal_can_insert && ((2 * col_temp) >= col_lendiff || _rl_term_IC) && (!_rl_term_autowrap || !gl))
{
/* If lendiff > prompt_visible_length and _rl_last_c_pos == 0 and
_rl_horizontal_scroll_mode == 1, inserting the characters with
+3 -1
View File
@@ -1,7 +1,7 @@
/* make_cmd.c -- Functions for making instances of the various
parser constructs. */
/* Copyright (C) 1989-2005 Free Software Foundation, Inc.
/* Copyright (C) 1989-2007 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -771,7 +771,9 @@ make_function_def (name, command, lineno, lstart)
if (bash_source_a && array_num_elements (bash_source_a) > 0)
temp->source_file = array_reference (bash_source_a, 0);
#endif
#if defined (DEBUGGER)
bind_function_def (name->word, temp);
#endif
temp->source_file = 0;
return (make_command (cm_function_def, (SIMPLE_COM *)temp));
+858
View File
@@ -0,0 +1,858 @@
/* make_cmd.c -- Functions for making instances of the various
parser constructs. */
/* Copyright (C) 1989-2005 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 2, 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; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#include "config.h"
#include <stdio.h>
#include "bashtypes.h"
#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif
#include "filecntl.h"
#include "bashansi.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "bashintl.h"
#include "syntax.h"
#include "command.h"
#include "general.h"
#include "error.h"
#include "flags.h"
#include "make_cmd.h"
#include "dispose_cmd.h"
#include "variables.h"
#include "subst.h"
#include "input.h"
#include "ocache.h"
#include "externs.h"
#if defined (JOB_CONTROL)
#include "jobs.h"
#endif
#include "shmbutil.h"
extern int line_number, current_command_line_count;
extern int last_command_exit_value;
/* Object caching */
sh_obj_cache_t wdcache = {0, 0, 0};
sh_obj_cache_t wlcache = {0, 0, 0};
#define WDCACHESIZE 60
#define WLCACHESIZE 60
static COMMAND *make_for_or_select __P((enum command_type, WORD_DESC *, WORD_LIST *, COMMAND *, int));
#if defined (ARITH_FOR_COMMAND)
static WORD_LIST *make_arith_for_expr __P((char *));
#endif
static COMMAND *make_until_or_while __P((enum command_type, COMMAND *, COMMAND *));
void
cmd_init ()
{
ocache_create (wdcache, WORD_DESC, WDCACHESIZE);
ocache_create (wlcache, WORD_LIST, WLCACHESIZE);
}
WORD_DESC *
alloc_word_desc ()
{
WORD_DESC *temp;
ocache_alloc (wdcache, WORD_DESC, temp);
temp->flags = 0;
temp->word = 0;
return temp;
}
WORD_DESC *
make_bare_word (string)
const char *string;
{
WORD_DESC *temp;
temp = alloc_word_desc ();
if (*string)
temp->word = savestring (string);
else
{
temp->word = (char *)xmalloc (1);
temp->word[0] = '\0';
}
return (temp);
}
WORD_DESC *
make_word_flags (w, string)
WORD_DESC *w;
const char *string;
{
register int i;
size_t slen;
DECLARE_MBSTATE;
i = 0;
slen = strlen (string);
while (i < slen)
{
switch (string[i])
{
case '$':
w->flags |= W_HASDOLLAR;
break;
case '\\':
break; /* continue the loop */
case '\'':
case '`':
case '"':
w->flags |= W_QUOTED;
break;
}
ADVANCE_CHAR (string, slen, i);
}
return (w);
}
WORD_DESC *
make_word (string)
const char *string;
{
WORD_DESC *temp;
temp = make_bare_word (string);
return (make_word_flags (temp, string));
}
WORD_DESC *
make_word_from_token (token)
int token;
{
char tokenizer[2];
tokenizer[0] = token;
tokenizer[1] = '\0';
return (make_word (tokenizer));
}
WORD_LIST *
make_word_list (word, wlink)
WORD_DESC *word;
WORD_LIST *wlink;
{
WORD_LIST *temp;
ocache_alloc (wlcache, WORD_LIST, temp);
temp->word = word;
temp->next = wlink;
return (temp);
}
COMMAND *
make_command (type, pointer)
enum command_type type;
SIMPLE_COM *pointer;
{
COMMAND *temp;
temp = (COMMAND *)xmalloc (sizeof (COMMAND));
temp->type = type;
temp->value.Simple = pointer;
temp->value.Simple->flags = temp->flags = 0;
temp->redirects = (REDIRECT *)NULL;
return (temp);
}
COMMAND *
command_connect (com1, com2, connector)
COMMAND *com1, *com2;
int connector;
{
CONNECTION *temp;
temp = (CONNECTION *)xmalloc (sizeof (CONNECTION));
temp->connector = connector;
temp->first = com1;
temp->second = com2;
return (make_command (cm_connection, (SIMPLE_COM *)temp));
}
static COMMAND *
make_for_or_select (type, name, map_list, action, lineno)
enum command_type type;
WORD_DESC *name;
WORD_LIST *map_list;
COMMAND *action;
int lineno;
{
FOR_COM *temp;
temp = (FOR_COM *)xmalloc (sizeof (FOR_COM));
temp->flags = 0;
temp->name = name;
temp->line = lineno;
temp->map_list = map_list;
temp->action = action;
return (make_command (type, (SIMPLE_COM *)temp));
}
COMMAND *
make_for_command (name, map_list, action, lineno)
WORD_DESC *name;
WORD_LIST *map_list;
COMMAND *action;
int lineno;
{
return (make_for_or_select (cm_for, name, map_list, action, lineno));
}
COMMAND *
make_select_command (name, map_list, action, lineno)
WORD_DESC *name;
WORD_LIST *map_list;
COMMAND *action;
int lineno;
{
#if defined (SELECT_COMMAND)
return (make_for_or_select (cm_select, name, map_list, action, lineno));
#else
last_command_exit_value = 2;
return ((COMMAND *)NULL);
#endif
}
#if defined (ARITH_FOR_COMMAND)
static WORD_LIST *
make_arith_for_expr (s)
char *s;
{
WORD_LIST *result;
WORD_DESC *wd;
if (s == 0 || *s == '\0')
return ((WORD_LIST *)NULL);
wd = make_word (s);
wd->flags |= W_NOGLOB|W_NOSPLIT|W_QUOTED|W_DQUOTE; /* no word splitting or globbing */
result = make_word_list (wd, (WORD_LIST *)NULL);
return result;
}
#endif
/* Note that this function calls dispose_words on EXPRS, since it doesn't
use the word list directly. We free it here rather than at the caller
because no other function in this file requires that the caller free
any arguments. */
COMMAND *
make_arith_for_command (exprs, action, lineno)
WORD_LIST *exprs;
COMMAND *action;
int lineno;
{
#if defined (ARITH_FOR_COMMAND)
ARITH_FOR_COM *temp;
WORD_LIST *init, *test, *step;
char *s, *t, *start;
int nsemi;
init = test = step = (WORD_LIST *)NULL;
/* Parse the string into the three component sub-expressions. */
start = t = s = exprs->word->word;
for (nsemi = 0; ;)
{
/* skip whitespace at the start of each sub-expression. */
while (whitespace (*s))
s++;
start = s;
/* skip to the semicolon or EOS */
while (*s && *s != ';')
s++;
t = (s > start) ? substring (start, 0, s - start) : (char *)NULL;
nsemi++;
switch (nsemi)
{
case 1:
init = make_arith_for_expr (t);
break;
case 2:
test = make_arith_for_expr (t);
break;
case 3:
step = make_arith_for_expr (t);
break;
}
FREE (t);
if (*s == '\0')
break;
s++; /* skip over semicolon */
}
if (nsemi != 3)
{
if (nsemi < 3)
parser_error (lineno, _("syntax error: arithmetic expression required"));
else
parser_error (lineno, _("syntax error: `;' unexpected"));
parser_error (lineno, _("syntax error: `((%s))'"), exprs->word->word);
last_command_exit_value = 2;
return ((COMMAND *)NULL);
}
temp = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM));
temp->flags = 0;
temp->line = lineno;
temp->init = init ? init : make_arith_for_expr ("1");
temp->test = test ? test : make_arith_for_expr ("1");
temp->step = step ? step : make_arith_for_expr ("1");
temp->action = action;
dispose_words (exprs);
return (make_command (cm_arith_for, (SIMPLE_COM *)temp));
#else
dispose_words (exprs);
last_command_exit_value = 2;
return ((COMMAND *)NULL);
#endif /* ARITH_FOR_COMMAND */
}
COMMAND *
make_group_command (command)
COMMAND *command;
{
GROUP_COM *temp;
temp = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
temp->command = command;
return (make_command (cm_group, (SIMPLE_COM *)temp));
}
COMMAND *
make_case_command (word, clauses, lineno)
WORD_DESC *word;
PATTERN_LIST *clauses;
int lineno;
{
CASE_COM *temp;
temp = (CASE_COM *)xmalloc (sizeof (CASE_COM));
temp->flags = 0;
temp->line = lineno;
temp->word = word;
temp->clauses = REVERSE_LIST (clauses, PATTERN_LIST *);
return (make_command (cm_case, (SIMPLE_COM *)temp));
}
PATTERN_LIST *
make_pattern_list (patterns, action)
WORD_LIST *patterns;
COMMAND *action;
{
PATTERN_LIST *temp;
temp = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
temp->patterns = REVERSE_LIST (patterns, WORD_LIST *);
temp->action = action;
temp->next = NULL;
temp->flags = 0;
return (temp);
}
COMMAND *
make_if_command (test, true_case, false_case)
COMMAND *test, *true_case, *false_case;
{
IF_COM *temp;
temp = (IF_COM *)xmalloc (sizeof (IF_COM));
temp->flags = 0;
temp->test = test;
temp->true_case = true_case;
temp->false_case = false_case;
return (make_command (cm_if, (SIMPLE_COM *)temp));
}
static COMMAND *
make_until_or_while (which, test, action)
enum command_type which;
COMMAND *test, *action;
{
WHILE_COM *temp;
temp = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
temp->flags = 0;
temp->test = test;
temp->action = action;
return (make_command (which, (SIMPLE_COM *)temp));
}
COMMAND *
make_while_command (test, action)
COMMAND *test, *action;
{
return (make_until_or_while (cm_while, test, action));
}
COMMAND *
make_until_command (test, action)
COMMAND *test, *action;
{
return (make_until_or_while (cm_until, test, action));
}
COMMAND *
make_arith_command (exp)
WORD_LIST *exp;
{
#if defined (DPAREN_ARITHMETIC)
COMMAND *command;
ARITH_COM *temp;
command = (COMMAND *)xmalloc (sizeof (COMMAND));
command->value.Arith = temp = (ARITH_COM *)xmalloc (sizeof (ARITH_COM));
temp->flags = 0;
temp->line = line_number;
temp->exp = exp;
command->type = cm_arith;
command->redirects = (REDIRECT *)NULL;
command->flags = 0;
return (command);
#else
last_command_exit_value = 2;
return ((COMMAND *)NULL);
#endif
}
#if defined (COND_COMMAND)
struct cond_com *
make_cond_node (type, op, left, right)
int type;
WORD_DESC *op;
struct cond_com *left, *right;
{
COND_COM *temp;
temp = (COND_COM *)xmalloc (sizeof (COND_COM));
temp->flags = 0;
temp->line = line_number;
temp->type = type;
temp->op = op;
temp->left = left;
temp->right = right;
return (temp);
}
#endif
COMMAND *
make_cond_command (cond_node)
COND_COM *cond_node;
{
#if defined (COND_COMMAND)
COMMAND *command;
command = (COMMAND *)xmalloc (sizeof (COMMAND));
command->value.Cond = cond_node;
command->type = cm_cond;
command->redirects = (REDIRECT *)NULL;
command->flags = 0;
command->line = cond_node ? cond_node->line : 0;
return (command);
#else
last_command_exit_value = 2;
return ((COMMAND *)NULL);
#endif
}
COMMAND *
make_bare_simple_command ()
{
COMMAND *command;
SIMPLE_COM *temp;
command = (COMMAND *)xmalloc (sizeof (COMMAND));
command->value.Simple = temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
temp->flags = 0;
temp->line = line_number;
temp->words = (WORD_LIST *)NULL;
temp->redirects = (REDIRECT *)NULL;
command->type = cm_simple;
command->redirects = (REDIRECT *)NULL;
command->flags = 0;
return (command);
}
/* Return a command which is the connection of the word or redirection
in ELEMENT, and the command * or NULL in COMMAND. */
COMMAND *
make_simple_command (element, command)
ELEMENT element;
COMMAND *command;
{
/* If we are starting from scratch, then make the initial command
structure. Also note that we have to fill in all the slots, since
malloc doesn't return zeroed space. */
if (!command)
command = make_bare_simple_command ();
if (element.word)
command->value.Simple->words = make_word_list (element.word, command->value.Simple->words);
else if (element.redirect)
{
REDIRECT *r = element.redirect;
/* Due to the way <> is implemented, there may be more than a single
redirection in element.redirect. We just follow the chain as far
as it goes, and hook onto the end. */
while (r->next)
r = r->next;
r->next = command->value.Simple->redirects;
command->value.Simple->redirects = element.redirect;
}
return (command);
}
/* Because we are Bourne compatible, we read the input for this
<< or <<- redirection now, from wherever input is coming from.
We store the input read into a WORD_DESC. Replace the text of
the redirectee.word with the new input text. If <<- is on,
then remove leading TABS from each line. */
void
make_here_document (temp)
REDIRECT *temp;
{
int kill_leading, redir_len;
char *redir_word, *document, *full_line;
int document_index, document_size, delim_unquoted;
if (temp->instruction != r_deblank_reading_until &&
temp->instruction != r_reading_until)
{
internal_error (_("make_here_document: bad instruction type %d"), temp->instruction);
return;
}
kill_leading = temp->instruction == r_deblank_reading_until;
document = (char *)NULL;
document_index = document_size = 0;
/* Quote removal is the only expansion performed on the delimiter
for here documents, making it an extremely special case. */
redir_word = string_quote_removal (temp->redirectee.filename->word, 0);
/* redirection_expand will return NULL if the expansion results in
multiple words or no words. Check for that here, and just abort
this here document if it does. */
if (redir_word)
redir_len = strlen (redir_word);
else
{
temp->here_doc_eof = (char *)xmalloc (1);
temp->here_doc_eof[0] = '\0';
goto document_done;
}
free (temp->redirectee.filename->word);
temp->here_doc_eof = redir_word;
/* Read lines from wherever lines are coming from.
For each line read, if kill_leading, then kill the
leading tab characters.
If the line matches redir_word exactly, then we have
manufactured the document. Otherwise, add the line to the
list of lines in the document. */
/* If the here-document delimiter was quoted, the lines should
be read verbatim from the input. If it was not quoted, we
need to perform backslash-quoted newline removal. */
delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0;
while (full_line = read_secondary_line (delim_unquoted))
{
register char *line;
int len;
line = full_line;
line_number++;
/* If set -v is in effect, echo the line read. read_secondary_line/
read_a_line leaves the newline at the end, so don't print another. */
if (echo_input_at_read)
fprintf (stderr, "%s", line);
if (kill_leading && *line)
{
/* Hack: To be compatible with some Bourne shells, we
check the word before stripping the whitespace. This
is a hack, though. */
if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
goto document_done;
while (*line == '\t')
line++;
}
if (*line == 0)
continue;
if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
goto document_done;
len = strlen (line);
if (len + document_index >= document_size)
{
document_size = document_size ? 2 * (document_size + len) : len + 2;
document = (char *)xrealloc (document, document_size);
}
/* len is guaranteed to be > 0 because of the check for line
being an empty string before the call to strlen. */
FASTCOPY (line, document + document_index, len);
document_index += len;
}
document_done:
if (document)
document[document_index] = '\0';
else
{
document = (char *)xmalloc (1);
document[0] = '\0';
}
temp->redirectee.filename->word = document;
}
/* Generate a REDIRECT from SOURCE, DEST, and INSTRUCTION.
INSTRUCTION is the instruction type, SOURCE is a file descriptor,
and DEST is a file descriptor or a WORD_DESC *. */
REDIRECT *
make_redirection (source, instruction, dest_and_filename)
int source;
enum r_instruction instruction;
REDIRECTEE dest_and_filename;
{
REDIRECT *temp;
WORD_DESC *w;
int wlen;
intmax_t lfd;
temp = (REDIRECT *)xmalloc (sizeof (REDIRECT));
/* First do the common cases. */
temp->redirector = source;
temp->redirectee = dest_and_filename;
temp->instruction = instruction;
temp->flags = 0;
temp->next = (REDIRECT *)NULL;
switch (instruction)
{
case r_output_direction: /* >foo */
case r_output_force: /* >| foo */
case r_err_and_out: /* command &>filename */
temp->flags = O_TRUNC | O_WRONLY | O_CREAT;
break;
case r_appending_to: /* >>foo */
temp->flags = O_APPEND | O_WRONLY | O_CREAT;
break;
case r_input_direction: /* <foo */
case r_inputa_direction: /* foo & makes this. */
temp->flags = O_RDONLY;
break;
case r_input_output: /* <>foo */
temp->flags = O_RDWR | O_CREAT;
break;
case r_deblank_reading_until: /* <<-foo */
case r_reading_until: /* << foo */
case r_reading_string: /* <<< foo */
case r_close_this: /* <&- */
case r_duplicating_input: /* 1<&2 */
case r_duplicating_output: /* 1>&2 */
break;
/* the parser doesn't pass these. */
case r_move_input: /* 1<&2- */
case r_move_output: /* 1>&2- */
case r_move_input_word: /* 1<&$foo- */
case r_move_output_word: /* 1>&$foo- */
break;
/* The way the lexer works we have to do this here. */
case r_duplicating_input_word: /* 1<&$foo */
case r_duplicating_output_word: /* 1>&$foo */
w = dest_and_filename.filename;
wlen = strlen (w->word) - 1;
if (w->word[wlen] == '-') /* Yuck */
{
w->word[wlen] = '\0';
if (all_digits (w->word) && legal_number (w->word, &lfd) && lfd == (int)lfd)
{
dispose_word (w);
temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input : r_move_output;
temp->redirectee.dest = lfd;
}
else
temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input_word : r_move_output_word;
}
break;
default:
programming_error (_("make_redirection: redirection instruction `%d' out of range"), instruction);
abort ();
break;
}
return (temp);
}
COMMAND *
make_function_def (name, command, lineno, lstart)
WORD_DESC *name;
COMMAND *command;
int lineno, lstart;
{
FUNCTION_DEF *temp;
#if defined (ARRAY_VARS)
SHELL_VAR *bash_source_v;
ARRAY *bash_source_a;
#endif
temp = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
temp->command = command;
temp->name = name;
temp->line = lineno;
temp->flags = 0;
command->line = lstart;
/* Information used primarily for debugging. */
temp->source_file = 0;
#if defined (ARRAY_VARS)
GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
if (bash_source_a && array_num_elements (bash_source_a) > 0)
temp->source_file = array_reference (bash_source_a, 0);
#endif
#if defined (DEBUGGER)
bind_function_def (name->word, temp);
#endif
temp->source_file = 0;
return (make_command (cm_function_def, (SIMPLE_COM *)temp));
}
COMMAND *
make_subshell_command (command)
COMMAND *command;
{
SUBSHELL_COM *temp;
temp = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM));
temp->command = command;
temp->flags = CMD_WANT_SUBSHELL;
return (make_command (cm_subshell, (SIMPLE_COM *)temp));
}
/* Reverse the word list and redirection list in the simple command
has just been parsed. It seems simpler to do this here the one
time then by any other method that I can think of. */
COMMAND *
clean_simple_command (command)
COMMAND *command;
{
if (command->type != cm_simple)
command_error ("clean_simple_command", CMDERR_BADTYPE, command->type, 0);
else
{
command->value.Simple->words =
REVERSE_LIST (command->value.Simple->words, WORD_LIST *);
command->value.Simple->redirects =
REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
}
return (command);
}
/* The Yacc grammar productions have a problem, in that they take a
list followed by an ampersand (`&') and do a simple command connection,
making the entire list effectively asynchronous, instead of just
the last command. This means that when the list is executed, all
the commands have stdin set to /dev/null when job control is not
active, instead of just the last. This is wrong, and needs fixing
up. This function takes the `&' and applies it to the last command
in the list. This is done only for lists connected by `;'; it makes
`;' bind `tighter' than `&'. */
COMMAND *
connect_async_list (command, command2, connector)
COMMAND *command, *command2;
int connector;
{
COMMAND *t, *t1, *t2;
t1 = command;
t = command->value.Connection->second;
if (!t || (command->flags & CMD_WANT_SUBSHELL) ||
command->value.Connection->connector != ';')
{
t = command_connect (command, command2, connector);
return t;
}
/* This is just defensive programming. The Yacc precedence rules
will generally hand this function a command where t points directly
to the command we want (e.g. given a ; b ; c ; d &, t1 will point
to the `a ; b ; c' list and t will be the `d'). We only want to do
this if the list is not being executed as a unit in the background
with `( ... )', so we have to check for CMD_WANT_SUBSHELL. That's
the only way to tell. */
while (((t->flags & CMD_WANT_SUBSHELL) == 0) && t->type == cm_connection &&
t->value.Connection->connector == ';')
{
t1 = t;
t = t->value.Connection->second;
}
/* Now we have t pointing to the last command in the list, and
t1->value.Connection->second == t. */
t2 = command_connect (t, command2, connector);
t1->value.Connection->second = t2;
return command;
}
+10 -6
View File
@@ -1039,13 +1039,14 @@ print_function_def (func)
/* Return the string representation of the named function.
NAME is the name of the function.
COMMAND is the function body. It should be a GROUP_COM.
MULTI_LINE is non-zero to pretty-print, or zero for all on one line.
flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
flags&FUNC_EXTERNAL means convert from internal to external form
*/
char *
named_function_string (name, command, multi_line)
named_function_string (name, command, flags)
char *name;
COMMAND *command;
int multi_line;
int flags;
{
char *result;
int old_indent, old_amount;
@@ -1061,7 +1062,7 @@ named_function_string (name, command, multi_line)
cprintf ("() ");
if (multi_line == 0)
if ((flags & FUNC_MULTILINE) == 0)
{
indentation = 1;
indentation_amount = 0;
@@ -1074,7 +1075,7 @@ named_function_string (name, command, multi_line)
inside_function_def++;
cprintf (multi_line ? "{ \n" : "{ ");
cprintf ((flags & FUNC_MULTILINE) ? "{ \n" : "{ ");
cmdcopy = copy_command (command);
/* Take any redirections specified in the function definition (which should
@@ -1104,7 +1105,7 @@ named_function_string (name, command, multi_line)
result = the_printed_command;
if (!multi_line)
if ((flags & FUNC_MULTILINE) == 0)
{
#if 0
register int i;
@@ -1122,6 +1123,9 @@ named_function_string (name, command, multi_line)
dispose_command (cmdcopy);
if (flags & FUNC_EXTERNAL)
result = remove_quoted_escapes (result);
return (result);
}
+24 -35
View File
@@ -106,8 +106,6 @@ int command_string_index = 0;
/* Non-zero means the stuff being printed is inside of a function def. */
static int inside_function_def;
static int inside_pipeline;
static int skip_this_indent;
static int was_heredoc;
@@ -135,7 +133,7 @@ char *
make_command_string (command)
COMMAND *command;
{
command_string_index = was_heredoc = inside_pipeline = 0;
command_string_index = was_heredoc = 0;
make_command_string_internal (command);
return (the_printed_command);
}
@@ -217,11 +215,7 @@ make_command_string_internal (command)
case cm_connection:
skip_this_indent++;
if (command->value.Connection->connector == '|')
inside_pipeline = 1;
make_command_string_internal (command->value.Connection->first);
if (command->value.Connection->connector == '|')
inside_pipeline = 0;
switch (command->value.Connection->connector)
{
@@ -229,10 +223,7 @@ make_command_string_internal (command)
case '|':
{
char c = command->value.Connection->connector;
if (c == '&' || was_heredoc == 0)
cprintf (" %c", c);
else
was_heredoc = 0;
cprintf (" %c", c);
if (c != '&' || command->value.Connection->second)
{
cprintf (" ");
@@ -860,10 +851,6 @@ print_redirection_list (redirects)
print the here documents. */
if (heredocs)
{
if (inside_pipeline)
{
itrace("print_redirection_list: here documents inside pipeline");
}
cprintf (" ");
for (hdtail = heredocs; hdtail; hdtail = hdtail->next)
{
@@ -881,7 +868,6 @@ print_redirection (redirect)
{
int kill_leading, redirector, redir_fd;
WORD_DESC *redirectee;
char *x;
kill_leading = 0;
redirectee = redirect->redirectee.filename;
@@ -919,16 +905,17 @@ print_redirection (redirect)
if (redirector != 0)
cprintf ("%d", redirector);
/* If the here document delimiter is quoted, single-quote it. */
x = (redirect->redirectee.filename->flags & W_QUOTED)
? sh_single_quote (redirect->here_doc_eof)
: redirect->here_doc_eof;
cprintf ("<<%s%s", kill_leading? "-" : "", x);
if (x != redirect->here_doc_eof)
free (x);
if (inside_pipeline)
cprintf (" |");
cprintf ("\n");
cprintf ("%s%s", redirect->redirectee.filename->word, redirect->here_doc_eof);
if (redirect->redirectee.filename->flags & W_QUOTED)
{
char *x;
x = sh_single_quote (redirect->here_doc_eof);
cprintf ("<<%s%s\n", kill_leading? "-" : "", x);
free (x);
}
else
cprintf ("<<%s%s\n", kill_leading? "-" : "", redirect->here_doc_eof);
cprintf ("%s%s",
redirect->redirectee.filename->word, redirect->here_doc_eof);
break;
case r_reading_string:
@@ -1004,7 +991,6 @@ reset_locals ()
{
inside_function_def = 0;
indentation = 0;
inside_pipeline = 0;
}
static void
@@ -1024,7 +1010,7 @@ print_function_def (func)
inside_function_def++;
indentation += indentation_amount;
cmdcopy = copy_command (func->command); /* possible mem leak on unwind-protect */
cmdcopy = copy_command (func->command);
if (cmdcopy->type == cm_group)
{
func_redirects = cmdcopy->redirects;
@@ -1053,13 +1039,14 @@ print_function_def (func)
/* Return the string representation of the named function.
NAME is the name of the function.
COMMAND is the function body. It should be a GROUP_COM.
MULTI_LINE is non-zero to pretty-print, or zero for all on one line.
flags&FUNC_MULTILINE is non-zero to pretty-print, or zero for all on one line.
flags&FUNC_EXTERNAL means convert from internal to external form
*/
char *
named_function_string (name, command, multi_line)
named_function_string (name, command, flags)
char *name;
COMMAND *command;
int multi_line;
int flags;
{
char *result;
int old_indent, old_amount;
@@ -1069,14 +1056,13 @@ named_function_string (name, command, multi_line)
old_indent = indentation;
old_amount = indentation_amount;
command_string_index = was_heredoc = 0;
inside_pipeline = 0;
if (name && *name)
cprintf ("%s ", name);
cprintf ("() ");
if (multi_line == 0)
if ((flags & FUNC_MULTILINE) == 0)
{
indentation = 1;
indentation_amount = 0;
@@ -1089,7 +1075,7 @@ named_function_string (name, command, multi_line)
inside_function_def++;
cprintf (multi_line ? "{ \n" : "{ ");
cprintf ((flags & FUNC_MULTILINE) ? "{ \n" : "{ ");
cmdcopy = copy_command (command);
/* Take any redirections specified in the function definition (which should
@@ -1119,7 +1105,7 @@ named_function_string (name, command, multi_line)
result = the_printed_command;
if (!multi_line)
if ((flags & FUNC_MULTILINE) == 0)
{
#if 0
register int i;
@@ -1137,6 +1123,9 @@ named_function_string (name, command, multi_line)
dispose_command (cmdcopy);
if (flags & FUNC_EXTERNAL)
remove_quoted_escapes (result);
return (result);
}
+16 -15
View File
@@ -1,6 +1,6 @@
/* redir.c -- Functions to perform input and output redirection. */
/* Copyright (C) 1997-2005 Free Software Foundation, Inc.
/* Copyright (C) 1997-2007 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -54,6 +54,8 @@ extern int errno;
# include "input.h"
#endif
#define SHELL_FD_BASE 10
int expanding_redir;
extern int posixly_correct;
@@ -481,7 +483,7 @@ redir_special_open (spec, filename, flags, mode, ri)
if (all_digits (filename+8) && legal_number (filename+8, &lfd) && lfd == (int)lfd)
{
fd = lfd;
fd = fcntl (fd, F_DUPFD, 10);
fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
}
else
fd = AMBIGUOUS_REDIRECT;
@@ -490,13 +492,13 @@ redir_special_open (spec, filename, flags, mode, ri)
#if !defined (HAVE_DEV_STDIN)
case RF_DEVSTDIN:
fd = fcntl (0, F_DUPFD, 10);
fd = fcntl (0, F_DUPFD, SHELL_FD_BASE);
break;
case RF_DEVSTDOUT:
fd = fcntl (1, F_DUPFD, 10);
fd = fcntl (1, F_DUPFD, SHELL_FD_BASE);
break;
case RF_DEVSTDERR:
fd = fcntl (2, F_DUPFD, 10);
fd = fcntl (2, F_DUPFD, SHELL_FD_BASE);
break;
#endif
@@ -888,7 +890,6 @@ do_redirection_internal (redirect, flags)
else
add_undo_close_redirect (redirector);
}
#if defined (BUFFERED_INPUT)
check_bash_input (redirector);
#endif
@@ -949,8 +950,6 @@ do_redirection_internal (redirect, flags)
return (0);
}
#define SHELL_FD_BASE 10
/* Remember the file descriptor associated with the slot FD,
on REDIRECTION_UNDO_LIST. Note that the list will be reversed
before it is executed. Any redirections that need to be undone
@@ -996,17 +995,19 @@ add_undo_redirect (fd, ri)
/* experimental: if we're saving a redirection to undo for a file descriptor
above SHELL_FD_BASE, add a redirection to be undone if the exec builtin
causes redirections to be discarded. */
if (fd >= SHELL_FD_BASE && ri != r_close_this)
causes redirections to be discarded. There needs to be a difference
between fds that are used to save other fds and then are the target of
user redirctions and fds that are just the target of user redirections.
We use the close-on-exec flag to tell the difference; fds > SHELL_FD_BASE
that have the close-on-exec flag set are assumed to be fds used internally
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);
#if 0
closer = copy_redirects (new_redirect);
add_exec_redirect (closer);
#else
new_redirect->flags |= RX_INTERNAL;
add_exec_redirect (new_redirect);
#endif
}
/* File descriptors used only for saving others should always be
+11 -3
View File
@@ -305,6 +305,7 @@ static int uidget __P((void));
static void init_interactive __P((void));
static void init_noninteractive __P((void));
static void init_interactive_script __P((void));
static void set_shell_name __P((char *));
static void shell_initialize __P((void));
@@ -1480,7 +1481,7 @@ open_shell_script (script_name)
/* But if a script is called with something like `bash -i scriptname',
we need to do a non-interactive setup here, since we didn't do it
before. */
init_noninteractive ();
init_interactive_script ();
free (filename);
return (fd);
@@ -1573,8 +1574,8 @@ set_shell_name (argv0)
static void
init_interactive ()
{
interactive_shell = startup_state = interactive = 1;
expand_aliases = 1;
expand_aliases = interactive_shell = startup_state = 1;
interactive = 1;
}
static void
@@ -1591,6 +1592,13 @@ init_noninteractive ()
#endif /* JOB_CONTROL */
}
static void
init_interactive_script ()
{
init_noninteractive ();
expand_aliases = interactive_shell = startup_state = 1;
}
void
get_current_user_info ()
{
+1 -2
View File
@@ -211,7 +211,6 @@ static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
static char *dequote_escapes __P((char *));
static char *make_quoted_char __P((int));
static WORD_LIST *quote_list __P((WORD_LIST *));
static char *remove_quoted_escapes __P((char *));
static char *remove_quoted_nulls __P((char *));
static int unquoted_substring __P((char *, char *));
@@ -3201,7 +3200,7 @@ dequote_list (list)
/* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
string. */
static char *
char *
remove_quoted_escapes (string)
char *string;
{
+4 -2
View File
@@ -136,6 +136,8 @@ size_t ifs_firstc_len;
unsigned char ifs_firstc;
#endif
int assigning_in_environment;
/* Extern functions and variables from different files. */
extern int last_command_exit_value, last_command_exit_signal;
extern int subshell_environment;
@@ -209,7 +211,7 @@ static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
static char *dequote_escapes __P((char *));
static char *make_quoted_char __P((int));
static WORD_LIST *quote_list __P((WORD_LIST *));
static char *remove_quoted_escapes __P((char *));
/*static*/ char *remove_quoted_escapes __P((char *));
static char *remove_quoted_nulls __P((char *));
static int unquoted_substring __P((char *, char *));
@@ -3199,7 +3201,7 @@ dequote_list (list)
/* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
string. */
static char *
/*static*/ char *
remove_quoted_escapes (string)
char *string;
{
+4 -1
View File
@@ -1,6 +1,6 @@
/* subst.h -- Names of externally visible functions in subst.c. */
/* Copyright (C) 1993-2004 Free Software Foundation, Inc.
/* Copyright (C) 1993-2007 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -181,6 +181,9 @@ extern char *quote_string __P((char *));
in a string. */
extern char *quote_escapes __P((char *));
/* And remove such quoted special characters. */
extern char *remove_quoted_escapes __P((char *));
/* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
backslash quoting rules for within double quotes. */
extern char *string_quote_removal __P((char *, int));
+270
View File
@@ -0,0 +1,270 @@
/* subst.h -- Names of externally visible functions in subst.c. */
/* Copyright (C) 1993-2004 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 2, 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; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_SUBST_H_)
#define _SUBST_H_
#include "stdc.h"
/* Constants which specify how to handle backslashes and quoting in
expand_word_internal (). Q_DOUBLE_QUOTES means to use the function
slashify_in_quotes () to decide whether the backslash should be
retained. Q_HERE_DOCUMENT means slashify_in_here_document () to
decide whether to retain the backslash. Q_KEEP_BACKSLASH means
to unconditionally retain the backslash. Q_PATQUOTE means that we're
expanding a pattern ${var%#[#%]pattern} in an expansion surrounded
by double quotes. */
#define Q_DOUBLE_QUOTES 0x01
#define Q_HERE_DOCUMENT 0x02
#define Q_KEEP_BACKSLASH 0x04
#define Q_PATQUOTE 0x08
#define Q_QUOTED 0x10
#define Q_ADDEDQUOTES 0x20
#define Q_QUOTEDNULL 0x40
/* Flag values controlling how assignment statements are treated. */
#define ASS_APPEND 0x01
#define ASS_MKLOCAL 0x02
/* Remove backslashes which are quoting backquotes from STRING. Modifies
STRING, and returns a pointer to it. */
extern char * de_backslash __P((char *));
/* Replace instances of \! in a string with !. */
extern void unquote_bang __P((char *));
/* Extract the $( construct in STRING, and return a new string.
Start extracting at (SINDEX) as if we had just seen "$(".
Make (SINDEX) get the position just after the matching ")". */
extern char *extract_command_subst __P((char *, int *));
/* Extract the $[ construct in STRING, and return a new string.
Start extracting at (SINDEX) as if we had just seen "$[".
Make (SINDEX) get the position just after the matching "]". */
extern char *extract_arithmetic_subst __P((char *, int *));
#if defined (PROCESS_SUBSTITUTION)
/* Extract the <( or >( construct in STRING, and return a new string.
Start extracting at (SINDEX) as if we had just seen "<(".
Make (SINDEX) get the position just after the matching ")". */
extern char *extract_process_subst __P((char *, char *, int *));
#endif /* PROCESS_SUBSTITUTION */
/* Extract the name of the variable to bind to from the assignment string. */
extern char *assignment_name __P((char *));
/* Return a single string of all the words present in LIST, separating
each word with SEP. */
extern char *string_list_internal __P((WORD_LIST *, char *));
/* Return a single string of all the words present in LIST, separating
each word with a space. */
extern char *string_list __P((WORD_LIST *));
/* Turn $* into a single string, obeying POSIX rules. */
extern char *string_list_dollar_star __P((WORD_LIST *));
/* Expand $@ into a single string, obeying POSIX rules. */
extern char *string_list_dollar_at __P((WORD_LIST *, int));
/* Perform quoted null character removal on each element of LIST.
This modifies LIST. */
extern void word_list_remove_quoted_nulls __P((WORD_LIST *));
/* This performs word splitting and quoted null character removal on
STRING. */
extern WORD_LIST *list_string __P((char *, char *, int));
extern char *get_word_from_string __P((char **, char *, char **));
extern char *strip_trailing_ifs_whitespace __P((char *, char *, int));
/* Given STRING, an assignment string, get the value of the right side
of the `=', and bind it to the left side. If EXPAND is true, then
perform tilde expansion, parameter expansion, command substitution,
and arithmetic expansion on the right-hand side. Do not perform word
splitting on the result of expansion. */
extern int do_assignment __P((char *));
extern int do_assignment_no_expand __P((char *));
extern int do_word_assignment __P((WORD_DESC *));
/* Append SOURCE to TARGET at INDEX. SIZE is the current amount
of space allocated to TARGET. SOURCE can be NULL, in which
case nothing happens. Gets rid of SOURCE by free ()ing it.
Returns TARGET in case the location has changed. */
extern char *sub_append_string __P((char *, char *, int *, int *));
/* Append the textual representation of NUMBER to TARGET.
INDEX and SIZE are as in SUB_APPEND_STRING. */
extern char *sub_append_number __P((intmax_t, char *, int *, int *));
/* Return the word list that corresponds to `$*'. */
extern WORD_LIST *list_rest_of_args __P((void));
/* Make a single large string out of the dollar digit variables,
and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
case of "$*" with respect to IFS. */
extern char *string_rest_of_args __P((int));
extern int number_of_args __P((void));
/* Expand STRING by performing parameter expansion, command substitution,
and arithmetic expansion. Dequote the resulting WORD_LIST before
returning it, but do not perform word splitting. The call to
remove_quoted_nulls () is made here because word splitting normally
takes care of quote removal. */
extern WORD_LIST *expand_string_unsplit __P((char *, int));
/* Expand the rhs of an assignment statement. */
extern WORD_LIST *expand_string_assignment __P((char *, int));
/* Expand a prompt string. */
extern WORD_LIST *expand_prompt_string __P((char *, int));
/* Expand STRING just as if you were expanding a word. This also returns
a list of words. Note that filename globbing is *NOT* done for word
or string expansion, just when the shell is expanding a command. This
does parameter expansion, command substitution, arithmetic expansion,
and word splitting. Dequote the resultant WORD_LIST before returning. */
extern WORD_LIST *expand_string __P((char *, int));
/* Convenience functions that expand strings to strings, taking care of
converting the WORD_LIST * returned by the expand_string* functions
to a string and deallocating the WORD_LIST *. */
extern char *expand_string_to_string __P((char *, int));
extern char *expand_string_unsplit_to_string __P((char *, int));
extern char *expand_assignment_string_to_string __P((char *, int));
/* Expand an arithmetic expression string */
extern char *expand_arith_string __P((char *, int));
/* De-quote quoted characters in STRING. */
extern char *dequote_string __P((char *));
/* De-quote quoted characters in each word in LIST. */
extern WORD_LIST *dequote_list __P((WORD_LIST *));
/* Expand WORD, performing word splitting on the result. This does
parameter expansion, command substitution, arithmetic expansion,
word splitting, and quote removal. */
extern WORD_LIST *expand_word __P((WORD_DESC *, int));
/* Expand WORD, but do not perform word splitting on the result. This
does parameter expansion, command substitution, arithmetic expansion,
and quote removal. */
extern WORD_LIST *expand_word_unsplit __P((WORD_DESC *, int));
extern WORD_LIST *expand_word_leave_quoted __P((WORD_DESC *, int));
/* Return the value of a positional parameter. This handles values > 10. */
extern char *get_dollar_var_value __P((intmax_t));
/* Quote a string to protect it from word splitting. */
extern char *quote_string __P((char *));
/* Quote escape characters (characters special to interals of expansion)
in a string. */
extern char *quote_escapes __P((char *));
/* And remove such quoted special characters. */
extern char *remove_quoted_escapes __P((char *));
/* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
backslash quoting rules for within double quotes. */
extern char *string_quote_removal __P((char *, int));
/* Perform quote removal on word WORD. This allocates and returns a new
WORD_DESC *. */
extern WORD_DESC *word_quote_removal __P((WORD_DESC *, int));
/* Perform quote removal on all words in LIST. If QUOTED is non-zero,
the members of the list are treated as if they are surrounded by
double quotes. Return a new list, or NULL if LIST is NULL. */
extern WORD_LIST *word_list_quote_removal __P((WORD_LIST *, int));
/* Called when IFS is changed to maintain some private variables. */
extern void setifs __P((SHELL_VAR *));
/* Return the value of $IFS, or " \t\n" if IFS is unset. */
extern char *getifs __P((void));
/* This splits a single word into a WORD LIST on $IFS, but only if the word
is not quoted. list_string () performs quote removal for us, even if we
don't do any splitting. */
extern WORD_LIST *word_split __P((WORD_DESC *, char *));
/* Take the list of words in LIST and do the various substitutions. Return
a new list of words which is the expanded list, and without things like
variable assignments. */
extern WORD_LIST *expand_words __P((WORD_LIST *));
/* Same as expand_words (), but doesn't hack variable or environment
variables. */
extern WORD_LIST *expand_words_no_vars __P((WORD_LIST *));
/* Perform the `normal shell expansions' on a WORD_LIST. These are
brace expansion, tilde expansion, parameter and variable substitution,
command substitution, arithmetic expansion, and word splitting. */
extern WORD_LIST *expand_words_shellexp __P((WORD_LIST *));
extern WORD_DESC *command_substitute __P((char *, int));
extern char *pat_subst __P((char *, char *, char *, int));
extern int fifos_pending __P((void));
extern void unlink_fifo_list __P((void));
extern WORD_LIST *list_string_with_quotes __P((char *));
#if defined (ARRAY_VARS)
extern char *extract_array_assignment_list __P((char *, int *));
#endif
#if defined (COND_COMMAND)
extern char *remove_backslashes __P((char *));
extern char *cond_expand_word __P((WORD_DESC *, int));
#endif
#if defined (READLINE)
extern int char_is_quoted __P((char *, int));
extern int unclosed_pair __P((char *, int, char *));
extern int skip_to_delim __P((char *, int, char *));
extern WORD_LIST *split_at_delims __P((char *, int, char *, int, int *, int *));
#endif
/* Variables used to keep track of the characters in IFS. */
extern SHELL_VAR *ifs_var;
extern char *ifs_value;
extern unsigned char ifs_cmap[];
#if defined (HANDLE_MULTIBYTE)
extern unsigned char ifs_firstc[];
extern size_t ifs_firstc_len;
#else
extern unsigned char ifs_firstc;
#endif
/* Evaluates to 1 if C is a character in $IFS. */
#define isifs(c) (ifs_cmap[(unsigned char)(c)] != 0)
/* How to determine the quoted state of the character C. */
#define QUOTED_CHAR(c) ((c) == CTLESC)
/* Is the first character of STRING a quoted NULL character? */
#define QUOTED_NULL(string) ((string)[0] == CTLNUL && (string)[1] == '\0')
#endif /* !_SUBST_H_ */
+2
View File
@@ -51,4 +51,6 @@ this is ohio-state
0
1
testb
bash: no job control in this shell
expand_aliases on
after
+57
View File
@@ -0,0 +1,57 @@
before exec1.sub: one two three
calling exec1.sub
aa bb cc dd ee
after exec1.sub with args: 0
after exec1.sub without args: 0
./execscript: line 20: notthere: command not found
127
/tmp/bash: notthere: No such file or directory
127
/bin/sh: /bin/sh: cannot execute binary file
126
./execscript: line 39: /: is a directory
126
/: /: is a directory
126
./execscript: line 46: .: /: is a directory
1
127
0
this is bashenv
./exec3.sub: line 3: /tmp/bash-notthere: No such file or directory
./exec3.sub: line 3: exec: /tmp/bash-notthere: cannot execute: No such file or directory
126
./execscript: line 68: notthere: No such file or directory
127
./execscript: line 71: notthere: No such file or directory
127
./execscript: line 74: notthere: No such file or directory
127
this is sh
this is sh
unset
ok
5
./exec5.sub: line 4: exec: bash-notthere: not found
127
this is ohio-state
0
1
1
0
42
42
0
1
1
0
0
1
0
1
testb
bash: cannot set terminal pgrp to 15044: Inappropriate ioctl for device
bash: no job control in this shell
expand_aliases on
after
+1
View File
@@ -0,0 +1 @@
shopt expand_aliases
+2
View File
@@ -105,6 +105,8 @@ ${THIS_SH} ./exec6.sub
# checks for properly deciding what constitutes an executable file
${THIS_SH} ./exec7.sub
${THIS_SH} -i ./exec8.sub
true | `echo true` &
echo after
+6
View File
@@ -156,3 +156,9 @@ argv[2] = <^?>
argv[1] = <^A^?>
argv[1] = <^A^?^A^?>
argv[1] = <^A^A^?>
0.net
0.net0
0.net
0.net
0.net
+2
View File
@@ -380,3 +380,5 @@ echo ${a//\\?/ }
echo ${a//\?/ }
${THIS_SH} ./exp1.sub
${THIS_SH} ./exp2.sub
+2
View File
@@ -378,3 +378,5 @@ a="a?b?c"
echo ${a//\\?/ }
echo ${a//\?/ }
${THIS_SH} ./exp1.sub
+12
View File
@@ -0,0 +1,12 @@
K=dvb0.net A=${K#dvb} eval echo \$A
unset K A
x=${K:=dvb0.net0} A=${K#dvb} eval echo \$A
unset K A
K=dvb0.net A=${K#dvb} echo "$A"
unset K A
K=dvb0.net A=${K#dvb} ; echo "$A"
unset K A
K=dvb0.net A=${K#dvb} eval echo '$A'
unset K A
K=dvb0.net A=${K#dvb} eval echo \$A
+4
View File
@@ -0,0 +1,4 @@
1
2
3
4
+3
View File
@@ -8,3 +8,6 @@ ok 2
aéb
0000000 141 303 251 142
0000004
-абвгдежзиклмноп - 16
-абвгдежзиклмноп- 15
-абвгд- 5
+3
View File
@@ -36,3 +36,6 @@ set a b
printf '%s\n' "$*"
printf '%s' "$*" | od -b
# display differences make this problematic
${THIS_SH} ./intl1.sub
+40
View File
@@ -0,0 +1,40 @@
export LC_ALL=en_US.UTF-8
a=$'\303\251'
echo "$a"
echo ${#a}
b=$'A\303\251B'
echo "$b"
echo ${b: -1}
c=AeB
echo ${c: -1}
unset a
a=$(printf '%b' 'A\303\251B')
IFS=$(printf '%b' '\303\251')
case "$a" in
"A${IFS}B") echo ok 1 ;;
*) echo bad 1 ;;
esac
set $a
case $1 in
A) echo ok 2 ;;
*) echo bad 2 ;;
esac
set a b
printf '%s\n' "$*"
printf '%s' "$*" | od -b
${THIS_SH} ./intl1.sub
+11
View File
@@ -0,0 +1,11 @@
LC_ALL=en_US.UTF-8
LANG=en_US.UTF-8
var='абвгдежзиклмноп '
echo -"$var"- ${#var}
read foo <<< "$var"
echo -"$foo"- ${#foo}
read -n 5 foo <<< "$var"
echo -"$foo"- ${#foo}
Binary file not shown.
+7
View File
@@ -300,3 +300,10 @@ printf "%s\n"
echo b
printf "%b\n" ''
printf "%b\n"
# bug in bash versions up to and including bash-3.2
v=yyy
printf -v var "%s" '/current/working/directory/*.@(m3|i3|ig|mg)'
shopt -s nullglob extglob
echo "x$(printf "%b" @(hugo))x"
printf -v var "%b" @(hugo); echo "x${var}x"
+9
View File
@@ -286,6 +286,8 @@ printf "%e\n" 4
printf "%4.2E\n" 4
printf "%4.2e\n" 4
printf "%08X\n" 2604292517
# make sure these format specifiers all output '' for empty string arguments
echo q
printf "%q\n" ""
@@ -298,3 +300,10 @@ printf "%s\n"
echo b
printf "%b\n" ''
printf "%b\n"
# bug in bash versions up to and including bash-3.2
v-=yyy
printf -v var "%s" '/current/working/directory/*.@(m3|i3|ig|mg)'
shopt -s nullglob extglob
echo "x$(printf "%b" @(hugo))x"
printf -v var "%b" @(hugo); echo "x${var}x"
+14
View File
@@ -100,3 +100,17 @@ c1 is 1
c2 is 2
c3 is 3
c4 is 4
fd 10
fd 8
fd 10
fd 8
1
2
3
4
1
2
3
4
cat /tmp/foo
whatsis
+11
View File
@@ -172,3 +172,14 @@ echo before block
echo after block
${THIS_SH} ./redir7.sub
${THIS_SH} ./redir8.sub
exec 9>&2
command exec 2>/tmp/foo
echo whatsis >&2
echo cat /tmp/foo
cat /tmp/foo
rm -f /tmp/foo
exec 2>&9
exec 9>&-
+176
View File
@@ -0,0 +1,176 @@
export LC_ALL=C
export LANG=C
# catch-all for remaining untested redirection stuff
set +o posix
echo abc > /tmp/redir-test
cat /tmp/redir-test
set -o noclobber
#this should be an error
echo def > /tmp/redir-test
cat /tmp/redir-test
# but this should succeed
echo def > /tmp/redir-test-2
cat /tmp/redir-test-2
# and so should this
echo def >| /tmp/redir-test
cat /tmp/redir-test
set +o noclobber
rm /tmp/redir-test /tmp/redir-test-2
# this should be an error
z="a b"
cat < $z
echo "Point 1"
exec 3</etc/passwd
exec 4>/tmp/bash-a
exec 5>/tmp/bash-b
echo "Point 2"
echo to a 1>&4
echo to b 1>&5
cat /tmp/bash-a
cat /tmp/bash-b
exec 11</dev/null
echo "Point 3"
echo to a 1>&4
echo to b 1>&5
cat /tmp/bash-a
cat /tmp/bash-b
exec 11<&-
echo "Point 4"
exec 6<>/tmp/bash-c
echo to c 1>&6
cat /tmp/bash-c
echo "Point 5"
rm -f /tmp/bash-a /tmp/bash-b /tmp/bash-c
#
# Test the effect of input buffering on the shell's input
#
${THIS_SH} < redir1.sub
# more open, close, duplicate file descriptors
${THIS_SH} ./redir3.sub < ./redir3.in1
# still more redirections
${THIS_SH} ./redir4.sub < redir4.in1
# various forms of null redirection
testf()
{
if [ -f "$1" ]; then
rm -f "$1"
else
echo oops -- $1 not found
fi
}
> /tmp/null-redir-a
testf /tmp/null-redir-a
$EXIT > /tmp/null-redir-b
testf /tmp/null-redir-b
( > /tmp/null-redir-c )
testf /tmp/null-redir-c
$EXIT > /tmp/null-redir-d &
wait
testf /tmp/null-redir-d
exit 3 | $EXIT > /tmp/null-redir-e
echo $? -- ${PIPESTATUS[@]}
testf /tmp/null-redir-e
exit 4 | > /tmp/null-redir-f
echo $? -- ${PIPESTATUS[@]}
testf /tmp/null-redir-f
> /tmp/null-redir-g &
wait
testf /tmp/null-redir-g
exec >/tmp/null-redir-h &
wait
testf /tmp/null-redir-h
# make sure async commands don't get /dev/null as stdin when an explicit
# input redirection is supplied
for x in 1 2 3; do
{ read line ; echo $line ; } &
wait
{ read line ; echo $line ; } &
wait
done << EOF
ab
cd
ef
gh
ij
kl
EOF
# make sure async commands get /dev/null as stdin in the absence of any
# input redirection
/bin/cat &
wait
echo $?
# make sure that loops work OK with here documents and are not run in
# subshells
while read line; do
echo $line
l2=$line
done << EOF
ab
cd
EOF
echo $l2
# These should not echo anything -- bug in versions before 2.04
( ( echo hello 1>&3 ) 3>&1 ) >/dev/null 2>&1
( ( echo hello 1>&3 ) 3>&1 ) >/dev/null 2>&1 | cat
# in posix mode, non-interactive shells are not allowed to perform
# filename expansion on input redirections, even if they expand to
# a single filename
set -o posix
cat < redir1.*
# test ksh93 dup-and-close (move fd) redirections
${THIS_SH} ./redir5.sub
# test behavior after a write error with a builtin command
${THIS_SH} ./redir6.sub
# problem with redirections using fds bash uses internally
: ${TMPDIR:=/tmp}
trap 'rm -f $TMPDIR/bash-redir-$$' 0 1 2 3 6 15
echo before block
{
echo before redir
exec 10>&1
echo after redir
} > $TMPDIR/bash-redir-$$
echo after block
${THIS_SH} ./redir7.sub
${THIS_SH} ./redir8.sub
+60
View File
@@ -0,0 +1,60 @@
rm -f u
${THIS_SH} -c 'exec 10>&1; echo fd 10 >&10' 10>u
cat u
rm -f u
${THIS_SH} -c 'exec 8>&1; echo fd 8 >&8' 8>u
cat u
rm -f u
exec 10>u
exec 10>&1; echo 'fd 10' >&10
cat u
rm -f u
exec 10>&-
exec 8>u
exec 8>&1; echo 'fd 8' >&8
cat u
rm -f u
exec 8>&-
rm -f infile
cat > infile <<EOF
1
2
3
4
EOF
exec 7<&0
exec 10<infile
exec 0<&10; cat <&10
exec 0<&7
exec 7<&-
exec 7<&0
exec 8<infile
exec 0<&8 ; cat <&8
exec 0<&7
exec 7<&-
exec 7<&0
exec 0</dev/null
exec 10<infile
exec 10<&0; cat <&10
exec 0<&7
exec 7<&-
exec 7<&0
exec 0</dev/null
exec 8<infile
exec 8<&0; cat <&8
exec 0<&7
exec 7<&-
exit 0
+2
View File
@@ -1,4 +1,6 @@
echo "warning: all of these tests will fail if arrays have not" >&2
echo "warning: been compiled into the shell" >&2
echo "warning: the BASH_ARGC and BASH_ARGV tests will fail if debugging support" >&2
echo "warning: has not been compiled into the shell" >&2
${THIS_SH} ./array.tests > /tmp/xx 2>&1
diff /tmp/xx array.right && rm -f /tmp/xx
+4
View File
@@ -0,0 +1,4 @@
echo "warning: all of these tests will fail if arrays have not" >&2
echo "warning: been compiled into the shell" >&2
${THIS_SH} ./array.tests > /tmp/xx 2>&1
diff /tmp/xx array.right && rm -f /tmp/xx
+5
View File
@@ -46,3 +46,8 @@ file
hits command
3 /tmp/bash
1 /bin/sh
f is a function
f ()
{
v='^A'
}
+7
View File
@@ -80,3 +80,10 @@ type -t $SHBASE
# make sure the hash table looks right
hash
# bug in versions of bash up to and including bash-3.2
f() {
v=$'\001'
}
type f | cat -v
+82
View File
@@ -0,0 +1,82 @@
set +o posix
hash -r
unalias -a
# this should echo nothing
type
# this should be a usage error
type -r ${THIS_SH}
# these should behave identically
type notthere
command -v notthere
alias m=more
unset -f func 2>/dev/null
func() { echo this is func; }
type -t func
type -t while
type -t builtin
type -t /bin/sh
type -t ${THIS_SH}
type -t mv
type func
# the following two should produce identical output
type while
type -a while
type builtin
type /bin/sh
command -v func
command -V func
command -v while
command -V while
# the following two lines should produce the same output
# post-3.0 patch makes command -v silent, as posix specifies
# first test with alias expansion off (should all fail or produce no output)
type -t m
type m
command -v m
alias -p
alias m
# then test with alias expansion on
shopt -s expand_aliases
type m
type -t m
command -v m
alias -p
alias m
command -V m
shopt -u expand_aliases
command -v builtin
command -V builtin
command -v /bin/sh
command -V /bin/sh
unset -f func
type func
unalias m
type m
hash -r
hash -p /bin/sh sh
type -p sh
SHBASE=${THIS_SH##*/}
hash -p /tmp/$SHBASE $SHBASE
type -p $SHBASE
type $SHBASE
type -t $SHBASE
# make sure the hash table looks right
hash
+14 -1
View File
@@ -985,8 +985,13 @@ void
print_var_function (var)
SHELL_VAR *var;
{
char *x;
if (function_p (var) && var_isset (var))
printf ("%s", named_function_string ((char *)NULL, function_cell(var), 1));
{
x = named_function_string ((char *)NULL, function_cell(var), FUNC_MULTILINE|FUNC_EXTERNAL);
printf ("%s", x);
}
}
/* **************************************************************** */
@@ -1599,7 +1604,11 @@ FUNCTION_DEF *
find_function_def (name)
const char *name;
{
#if defined (DEBUGGER)
return ((FUNCTION_DEF *)hash_lookup (name, shell_function_defs));
#else
return ((FUNCTION_DEF *)0);
#endif
}
/* Return the value of VAR. VAR is assumed to have been the result of a
@@ -2142,6 +2151,7 @@ bind_function (name, value)
return (entry);
}
#if defined (DEBUGGER)
/* Bind a function definition, which includes source file and line number
information in addition to the command, into the FUNCTION_DEF hash table.*/
void
@@ -2170,6 +2180,7 @@ bind_function_def (name, value)
elt->data = (PTR_T *)entry;
}
}
#endif /* DEBUGGER */
/* Add STRING, which is of the form foo=bar, to the temporary environment
HASH_TABLE (temporary_env). The functions in execute_cmd.c are
@@ -2362,6 +2373,7 @@ unbind_func (name)
return 0;
}
#if defined (DEBUGGER)
int
unbind_function_def (name)
const char *name;
@@ -2383,6 +2395,7 @@ unbind_function_def (name)
return 0;
}
#endif /* DEBUGGER */
/* Make the variable associated with NAME go away. HASH_LIST is the
hash table from which this variable should be deleted (either
+8 -2
View File
@@ -93,6 +93,7 @@ extern char *this_command_name;
extern char *command_execution_string;
extern time_t shell_start_time;
extern int assigning_in_environment;
extern int executing_builtin;
#if defined (READLINE)
extern int no_line_editing;
@@ -984,8 +985,13 @@ void
print_var_function (var)
SHELL_VAR *var;
{
char *x;
if (function_p (var) && var_isset (var))
printf ("%s", named_function_string ((char *)NULL, function_cell(var), 1));
{
x = named_function_string ((char *)NULL, function_cell(var), FUNC_MULTILINE|FUNC_EXTERNAL);
printf ("%s", x);
}
}
/* **************************************************************** */
@@ -1580,7 +1586,7 @@ SHELL_VAR *
find_variable (name)
const char *name;
{
return (find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || this_shell_builtin != 0))));
return (find_variable_internal (name, (expanding_redir == 0 && (assigning_in_environment || executing_builtin))));
}
/* Look up the function entry whose name matches STRING.