mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-23 05:47:59 +02:00
commit bash-20101015 snapshot
This commit is contained in:
@@ -10446,3 +10446,73 @@ builtins/{source.def,evalfile.c}
|
||||
how `command' can cancel effects of special builtin exit properties
|
||||
in the case of `dot file not found'
|
||||
|
||||
10/13
|
||||
-----
|
||||
lib/sh/strtrans.c
|
||||
- pass \c through unchanged if not escaping for `echo -e' and they are
|
||||
the final two characters in the string
|
||||
|
||||
10/15
|
||||
-----
|
||||
subst.c
|
||||
- extract_dollar_brace_string: fix problem with single quotes
|
||||
in unquoted ${...} for Posix compliance
|
||||
|
||||
10/16
|
||||
-----
|
||||
builtins/exec.def
|
||||
- catch return value from shell_execve; don't print duplicate error
|
||||
message if return value is EX_NOTFOUND. Make sure exit status
|
||||
from exec is 127 if command is not found
|
||||
|
||||
execute_cmd.c
|
||||
- fix typo (`saved_redirects' should be `saved redirects') in
|
||||
execute_function_or_builtin `command exec' case. Typo caused
|
||||
too much of the unwind-protect stack to be discarded
|
||||
- in same execute_function_or_builtin case, don't discard the
|
||||
`saved redirects' frame unconditionally; only discard it if
|
||||
saved_redirects is non-null in the `command exec' case. Fixes
|
||||
sh -c 'command exec; exit 1' hanging bug uncovered by FreeBSD
|
||||
sh test cases
|
||||
|
||||
10/18
|
||||
-----
|
||||
subst.c
|
||||
- when in posix mode, shell should not exit if a variable assignment
|
||||
error (e.g., assigning to readonly variable) occurs preceding a
|
||||
command that is not a special builtin. Fixes bug uncovered by
|
||||
FreeBSD sh test cases
|
||||
- when in posix mode, the ${!?} and ${!#} expansions are not indirect
|
||||
expansions, but posix word expansions involving the `!' variable
|
||||
|
||||
parse.y
|
||||
- fix parse_comsub so that it does not skip backslash-newline when
|
||||
parsing a comment
|
||||
|
||||
10/19
|
||||
-----
|
||||
subst.c
|
||||
- fix parameter_brace_expand so that an attempt to use the % or #
|
||||
expansions on an unset variable with -u set will cause a non-
|
||||
interactive shell to abort. Posix change
|
||||
- fix parameter_brace_expand so that an attempt to use pattern
|
||||
substitution or case modification expansions on an unset variable
|
||||
with -u set will cause and unbound variable error and make a
|
||||
non-interactive shell abort
|
||||
- change parameter_brace_expand_length to return INTMAX_MIN if a
|
||||
positional parameter is unset and -u is set
|
||||
- if parameter_brace_expand_length returns INTMAX_MIN when -u is set,
|
||||
treat it as an unbound variable error and make a non-interactive
|
||||
shell abort. Posix change
|
||||
- change parameter_brace_expand_length to return INTMAX_MIN if an
|
||||
implicit reference to array[0] is made ${#array} and array[0] is
|
||||
not set when -u is set
|
||||
|
||||
10/20
|
||||
-----
|
||||
builtins/cd.def
|
||||
- Posix 2008 says that if no matching directories are found in $CDPATH,
|
||||
use the directory name passed as an operand and go on. Posix change
|
||||
|
||||
doc/bashref.texi
|
||||
- change Posix mode section with latest additions and removals
|
||||
|
||||
@@ -10438,3 +10438,78 @@ execute_cmd.c
|
||||
- set executing_command_builtin in execute_builtin if the builtin is
|
||||
command_builtin. Unwind-protected in execute_function_or_builtin
|
||||
(like executing_builtin variable). Available for rest of shell
|
||||
|
||||
builtins/{source.def,evalfile.c}
|
||||
- make sure that non-interactive posix mode shells exit if the file
|
||||
argument to `.' is not found only if they are not being executed
|
||||
by the command builtin (executing_command_builtin == 0). This is
|
||||
how `command' can cancel effects of special builtin exit properties
|
||||
in the case of `dot file not found'
|
||||
|
||||
10/13
|
||||
-----
|
||||
lib/sh/strtrans.c
|
||||
- pass \c through unchanged if not escaping for `echo -e' and they are
|
||||
the final two characters in the string
|
||||
|
||||
10/15
|
||||
-----
|
||||
subst.c
|
||||
- extract_dollar_brace_string: fix problem with single quotes
|
||||
in unquoted ${...} for Posix compliance
|
||||
|
||||
10/16
|
||||
-----
|
||||
builtins/exec.def
|
||||
- catch return value from shell_execve; don't print duplicate error
|
||||
message if return value is EX_NOTFOUND. Make sure exit status
|
||||
from exec is 127 if command is not found
|
||||
|
||||
execute_cmd.c
|
||||
- fix typo (`saved_redirects' should be `saved redirects') in
|
||||
execute_function_or_builtin `command exec' case. Typo caused
|
||||
too much of the unwind-protect stack to be discarded
|
||||
- in same execute_function_or_builtin case, don't discard the
|
||||
`saved redirects' frame unconditionally; only discard it if
|
||||
saved_redirects is non-null in the `command exec' case. Fixes
|
||||
sh -c 'command exec; exit 1' hanging bug uncovered by FreeBSD
|
||||
sh test cases
|
||||
|
||||
10/18
|
||||
-----
|
||||
subst.c
|
||||
- when in posix mode, shell should not exit if a variable assignment
|
||||
error (e.g., assigning to readonly variable) occurs preceding a
|
||||
command that is not a special builtin. Fixes bug uncovered by
|
||||
FreeBSD sh test cases
|
||||
- when in posix mode, the ${!?} and ${!#} expansions are not indirect
|
||||
expansions, but posix word expansions involving the `!' variable
|
||||
|
||||
parse.y
|
||||
- fix parse_comsub so that it does not skip backslash-newline when
|
||||
parsing a comment
|
||||
|
||||
10/19
|
||||
-----
|
||||
subst.c
|
||||
- fix parameter_brace_expand so that an attempt to use the % or #
|
||||
expansions on an unset variable with -u set will cause a non-
|
||||
interactive shell to abort. Posix change
|
||||
- fix parameter_brace_expand so that an attempt to use pattern
|
||||
substitution or case modification expansions on an unset variable
|
||||
with -u set will cause and unbound variable error and make a
|
||||
non-interactive shell abort
|
||||
- change parameter_brace_expand_length to return INTMAX_MIN if a
|
||||
positional parameter is unset and -u is set
|
||||
- if parameter_brace_expand_length returns INTMAX_MIN when -u is set,
|
||||
treat it as an unbound variable error and make a non-interactive
|
||||
shell abort. Posix change
|
||||
- change parameter_brace_expand_length to return INTMAX_MIN if an
|
||||
implicit reference to array[0] is made ${#array} and array[0] is
|
||||
not set when -u is set
|
||||
|
||||
10/20
|
||||
-----
|
||||
builtins/cd.def
|
||||
- Posix 2008 says that if no matching directories are found in $CDPATH,
|
||||
use the directory name passed as an operand and go on. Posix change
|
||||
|
||||
@@ -283,6 +283,7 @@ cd_builtin (list)
|
||||
free (temp);
|
||||
}
|
||||
|
||||
#if 0 /* changed for bash-4.2 Posix cd description steps 5-6 */
|
||||
/* POSIX.2 says that if `.' does not appear in $CDPATH, we don't
|
||||
try the current directory, so we just punt now with an error
|
||||
message if POSIXLY_CORRECT is non-zero. The check for cdpath[0]
|
||||
@@ -293,6 +294,7 @@ cd_builtin (list)
|
||||
builtin_error ("%s: %s", dirname, strerror (ENOENT));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
dirname = list->word->word;
|
||||
|
||||
+14
-1
@@ -67,6 +67,8 @@ int cdspelling = 0;
|
||||
|
||||
int cdable_vars;
|
||||
|
||||
static int eflag; /* file scope so bindpwd() can see it */
|
||||
|
||||
$BUILTIN cd
|
||||
$FUNCTION cd_builtin
|
||||
$SHORT_DOC cd [-L|[-P [-e]]] [dir]
|
||||
@@ -141,6 +143,8 @@ bindpwd (no_symlinks)
|
||||
}
|
||||
|
||||
setpwd (dirname);
|
||||
if (dirname == 0 && eflag)
|
||||
r = EXECUTION_FAILURE;
|
||||
|
||||
if (dirname && dirname != the_current_working_directory)
|
||||
free (dirname);
|
||||
@@ -176,7 +180,7 @@ cd_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
char *dirname, *cdpath, *path, *temp;
|
||||
int path_index, no_symlinks, opt, lflag, eflag;
|
||||
int path_index, no_symlinks, opt, lflag;
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
if (restricted)
|
||||
@@ -211,6 +215,8 @@ cd_builtin (list)
|
||||
|
||||
lflag = (cdable_vars ? LCD_DOVARS : 0) |
|
||||
((interactive && cdspelling) ? LCD_DOSPELL : 0);
|
||||
if (eflag && no_symlinks == 0)
|
||||
eflag = 0;
|
||||
|
||||
if (list == 0)
|
||||
{
|
||||
@@ -284,8 +290,15 @@ cd_builtin (list)
|
||||
specifying the current directory. */
|
||||
if (posixly_correct && cdpath[0])
|
||||
{
|
||||
#if 0
|
||||
builtin_error ("%s: %s", dirname, strerror (ENOENT));
|
||||
return (EXECUTION_FAILURE);
|
||||
#else /* changed for bash-4.2 Posix cd description steps 5-6 */
|
||||
if (no_symlinks)
|
||||
dirname = list->word->word;
|
||||
else
|
||||
dirname =
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* evalstring.c - evaluate a string as one or more shell commands.
|
||||
|
||||
/* Copyright (C) 1996-2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -263,6 +263,7 @@ parse_and_execute (string, from_file, flags)
|
||||
|
||||
bitmap = new_fd_bitmap (FD_BITMAP_SIZE);
|
||||
begin_unwind_frame ("pe_dispose");
|
||||
itrace("begin_unwind_frame: pe_dispose");
|
||||
add_unwind_protect (dispose_fd_bitmap, bitmap);
|
||||
add_unwind_protect (dispose_command, command); /* XXX */
|
||||
|
||||
|
||||
+4
-2
@@ -212,7 +212,7 @@ exec_builtin (list)
|
||||
end_job_control ();
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
shell_execve (command, args, env);
|
||||
exit_value = shell_execve (command, args, env);
|
||||
|
||||
/* We have to set this to NULL because shell_execve has called realloc()
|
||||
to stuff more items at the front of the array, which may have caused
|
||||
@@ -221,7 +221,9 @@ exec_builtin (list)
|
||||
if (cleanenv == 0)
|
||||
adjust_shell_level (1);
|
||||
|
||||
if (executable_file (command) == 0)
|
||||
if (exit_value == EX_NOTFOUND) /* no duplicate error message */
|
||||
goto failed_exec;
|
||||
else if (executable_file (command) == 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot execute: %s"), command, strerror (errno));
|
||||
exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
|
||||
|
||||
+8
-2
@@ -150,7 +150,11 @@ exec_builtin (list)
|
||||
{
|
||||
if (file_isdir (args[0]))
|
||||
{
|
||||
#if defined (EISDIR)
|
||||
builtin_error (_("%s: cannot execute: %s"), args[0], strerror (EISDIR));
|
||||
#else
|
||||
builtin_error (_("%s: cannot execute: %s"), args[0], strerror (errno));
|
||||
#endif
|
||||
exit_value = EX_NOEXEC;
|
||||
}
|
||||
else
|
||||
@@ -208,7 +212,7 @@ exec_builtin (list)
|
||||
end_job_control ();
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
shell_execve (command, args, env);
|
||||
exit_value = shell_execve (command, args, env);
|
||||
|
||||
/* We have to set this to NULL because shell_execve has called realloc()
|
||||
to stuff more items at the front of the array, which may have caused
|
||||
@@ -217,7 +221,9 @@ exec_builtin (list)
|
||||
if (cleanenv == 0)
|
||||
adjust_shell_level (1);
|
||||
|
||||
if (executable_file (command) == 0)
|
||||
if (exit_value == EX_NOTFOUND)
|
||||
goto failed_exec;
|
||||
else if (executable_file (command) == 0)
|
||||
{
|
||||
builtin_error (_("%s: cannot execute: %s"), command, strerror (errno));
|
||||
exit_value = EX_NOEXEC; /* As per Posix.2, 3.14.6 */
|
||||
|
||||
+5
-1
@@ -35,7 +35,11 @@ value. If ARG is the null string each SIGNAL_SPEC is ignored by the
|
||||
shell and by the commands it invokes.
|
||||
|
||||
If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell. If
|
||||
a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command.
|
||||
a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command. If
|
||||
a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a
|
||||
script run by the . or source builtins finishes executing. A SIGNAL_SPEC
|
||||
of ERR means to execute ARG each time a command's failure would cause the
|
||||
shell to exit when the -e option is enabled.
|
||||
|
||||
If no arguments are supplied, trap prints the list of commands associated
|
||||
with each signal.
|
||||
|
||||
+4
-2
@@ -1,7 +1,7 @@
|
||||
This file is trap.def, from which is created trap.c.
|
||||
It implements the builtin "trap" in Bash.
|
||||
|
||||
Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -35,7 +35,9 @@ value. If ARG is the null string each SIGNAL_SPEC is ignored by the
|
||||
shell and by the commands it invokes.
|
||||
|
||||
If a SIGNAL_SPEC is EXIT (0) ARG is executed on exit from the shell. If
|
||||
a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command.
|
||||
a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command. If
|
||||
a SIGNAL_SPEC is RETURN, ARG is executed each time a shell function or a
|
||||
script run by the . or source builtins finishes executing.
|
||||
|
||||
If no arguments are supplied, trap prints the list of commands associated
|
||||
with each signal.
|
||||
|
||||
+2
-2
@@ -9366,8 +9366,8 @@ is
|
||||
.BR RETURN ,
|
||||
the command
|
||||
.I arg
|
||||
is executed each time a shell function or a script executed with the
|
||||
\fB.\fP or \fBsource\fP builtins finishes executing.
|
||||
is executed each time a shell function or a script executed with
|
||||
the \fB.\fP or \fBsource\fP builtins finishes executing.
|
||||
.if t .sp 0.5
|
||||
.if n .sp 1
|
||||
If a
|
||||
|
||||
+2
-2
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet@po.cwru.edu
|
||||
.\"
|
||||
.\" Last Change: Sat Aug 28 18:55:45 EDT 2010
|
||||
.\" Last Change: Mon Sep 6 22:07:38 EDT 2010
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2010 August 28" "GNU Bash-4.2"
|
||||
.TH BASH 1 "2010 September 6" "GNU Bash-4.2"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
|
||||
+5
-12
@@ -6694,14 +6694,6 @@ the @sc{posix} standard, and include things like passing incorrect options,
|
||||
redirection errors, variable assignment errors for assignments preceding
|
||||
the command name, and so on.
|
||||
|
||||
@item
|
||||
If @env{CDPATH} is set, the @code{cd} builtin will not implicitly
|
||||
append the current directory to it. This means that @code{cd} will
|
||||
fail if no valid directory name can be constructed from
|
||||
any of the entries in @env{$CDPATH}, even if the a directory with
|
||||
the same name as the name given as an argument to @code{cd} exists
|
||||
in the current directory.
|
||||
|
||||
@item
|
||||
A non-interactive shell exits with an error status if a variable
|
||||
assignment error occurs when no command name follows the assignment
|
||||
@@ -6709,6 +6701,11 @@ statements.
|
||||
A variable assignment error occurs, for example, when trying to assign
|
||||
a value to a readonly variable.
|
||||
|
||||
@item
|
||||
A non-interactive shell exists with an error status if a variable
|
||||
assignment error occurs in an assignment statement preceding a special
|
||||
builtin, but not with any other simple command.
|
||||
|
||||
@item
|
||||
A non-interactive shell exits with an error status if the iteration
|
||||
variable in a @code{for} statement or the selection variable in a
|
||||
@@ -6774,10 +6771,6 @@ constructed from @code{$PWD} and the directory name supplied as an argument
|
||||
does not refer to an existing directory, @code{cd} will fail instead of
|
||||
falling back to @var{physical} mode.
|
||||
|
||||
@item
|
||||
When the @code{pwd} builtin is supplied the @option{-P} option, it resets
|
||||
@code{$PWD} to a pathname containing no symlinks.
|
||||
|
||||
@item
|
||||
The @code{pwd} builtin verifies that the value it prints is the same as the
|
||||
current directory, even if it is not asked to check the file system with the
|
||||
|
||||
+15
-14
@@ -1135,7 +1135,7 @@ command (@pxref{Redirections}).
|
||||
The file descriptors can be utilized as arguments to shell commands
|
||||
and redirections using standard word expansions.
|
||||
|
||||
The process id of the shell spawned to execute the coprocess is
|
||||
The process ID of the shell spawned to execute the coprocess is
|
||||
available as the value of the variable @var{NAME}_PID.
|
||||
The @code{wait}
|
||||
builtin command may be used to wait for the coprocess to terminate.
|
||||
@@ -1382,7 +1382,7 @@ In the context where an assignment statement is assigning a value
|
||||
to a shell variable or array index (@pxref{Arrays}), the @samp{+=}
|
||||
operator can be used to
|
||||
append to or add to the variable's previous value.
|
||||
When @samp{+=} is applied to a variable for which the integer attribute
|
||||
When @samp{+=} is applied to a variable for which the @var{integer} attribute
|
||||
has been set, @var{value} is evaluated as an arithmetic expression and
|
||||
added to the variable's current value, which is also evaluated.
|
||||
When @samp{+=} is applied to an array variable using compound assignment
|
||||
@@ -1717,7 +1717,7 @@ Bash uses the value of the variable formed from the rest of
|
||||
expanded and that value is used in the rest of the substitution, rather
|
||||
than the value of @var{parameter} itself.
|
||||
This is known as @code{indirect expansion}.
|
||||
The exceptions to this are the expansions of $@{!@var{prefix*}@}
|
||||
The exceptions to this are the expansions of $@{!@var{prefix}@*}
|
||||
and $@{!@var{name}[@@]@}
|
||||
described below.
|
||||
The exclamation point must immediately follow the left brace in order to
|
||||
@@ -3061,7 +3061,7 @@ invocation if a new set of parameters is to be used.
|
||||
When the end of options is encountered, @code{getopts} exits with a
|
||||
return value greater than zero.
|
||||
@env{OPTIND} is set to the index of the first non-option argument,
|
||||
and @code{name} is set to @samp{?}.
|
||||
and @var{name} is set to @samp{?}.
|
||||
|
||||
@code{getopts}
|
||||
normally parses the positional parameters, but if more arguments are
|
||||
@@ -4141,8 +4141,8 @@ parameters, or to display the names and values of shell variables.
|
||||
@item set
|
||||
@btindex set
|
||||
@example
|
||||
set [--abefhkmnptuvxBCEHPT] [-o @var{option}] [@var{argument} @dots{}]
|
||||
set [+abefhkmnptuvxBCEHPT] [+o @var{option}] [@var{argument} @dots{}]
|
||||
set [--abefhkmnptuvxBCEHPT] [-o @var{option-name}] [@var{argument} @dots{}]
|
||||
set [+abefhkmnptuvxBCEHPT] [+o @var{option-name}] [@var{argument} @dots{}]
|
||||
@end example
|
||||
|
||||
If no options or arguments are supplied, @code{set} displays the names
|
||||
@@ -4503,18 +4503,19 @@ easy re-editing of multi-line commands.
|
||||
@item compat31
|
||||
If set, Bash
|
||||
changes its behavior to that of version 3.1 with respect to quoted
|
||||
arguments to the conditional command's =~ operator.
|
||||
arguments to the conditional command's @samp{=~} operator.
|
||||
|
||||
@item compat32
|
||||
If set, Bash
|
||||
changes its behavior to that of version 3.2 with respect to locale-specific
|
||||
string comparison when using the conditional command's < and > operators.
|
||||
string comparison when using the conditional command's @samp{<} and @samp{>}
|
||||
operators.
|
||||
|
||||
@item compat40
|
||||
If set, Bash
|
||||
changes its behavior to that of version 4.0 with respect to locale-specific
|
||||
string comparison when using the conditional command's < and > operators
|
||||
and the effect of interrupting a command list.
|
||||
string comparison when using the conditional command's @samp{<} and @samp{>}
|
||||
operators and the effect of interrupting a command list.
|
||||
|
||||
@item compat41
|
||||
If set, Bash, when in posix mode, treats a single quote in a double-quoted
|
||||
@@ -4850,13 +4851,13 @@ starts up, each shell option in the list will be enabled before
|
||||
reading any startup files. This variable is readonly.
|
||||
|
||||
@item BASHPID
|
||||
Expands to the process id of the current Bash process.
|
||||
Expands to the process ID of the current Bash process.
|
||||
This differs from @code{$$} under certain circumstances, such as subshells
|
||||
that do not require Bash to be re-initialized.
|
||||
|
||||
@item BASH_ALIASES
|
||||
An associative array variable whose members correspond to the internal
|
||||
list of aliases as maintained by the @code{alias} builtin
|
||||
list of aliases as maintained by the @code{alias} builtin.
|
||||
(@pxref{Bourne Shell Builtins}).
|
||||
Elements added to this array appear in the alias list; unsetting array
|
||||
elements cause aliases to be removed from the alias list.
|
||||
@@ -5728,7 +5729,7 @@ No other startup files are read.
|
||||
@subsubheading Invoked by remote shell daemon
|
||||
|
||||
Bash attempts to determine when it is being run with its standard input
|
||||
connected to a network connection, as if by the remote shell
|
||||
connected to a network connection, as when executed by the remote shell
|
||||
daemon, usually @code{rshd}, or the secure shell daemon @code{sshd}.
|
||||
If Bash determines it is being run in
|
||||
this fashion, it reads and executes commands from @file{~/.bashrc}, if that
|
||||
@@ -6132,7 +6133,7 @@ The value of a variable is evaluated as an arithmetic expression
|
||||
when it is referenced, or when a variable which has been given the
|
||||
@var{integer} attribute using @samp{declare -i} is assigned a value.
|
||||
A null value evaluates to 0.
|
||||
A shell variable need not have its integer attribute turned on
|
||||
A shell variable need not have its @var{integer} attribute turned on
|
||||
to be used in an expression.
|
||||
|
||||
Constants with a leading 0 are interpreted as octal numbers.
|
||||
|
||||
+3
-3
@@ -2,9 +2,9 @@
|
||||
Copyright (C) 1988-2010 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Mon Sep 6 22:08:10 EDT 2010
|
||||
@set LASTCHANGE Wed Oct 20 21:37:22 EDT 2010
|
||||
|
||||
@set EDITION 4.2
|
||||
@set VERSION 4.2
|
||||
@set UPDATED 6 September 2010
|
||||
@set UPDATED-MONTH September 2010
|
||||
@set UPDATED 20 October 2010
|
||||
@set UPDATED-MONTH October 2010
|
||||
|
||||
+3
-3
@@ -2,9 +2,9 @@
|
||||
Copyright (C) 1988-2010 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Sat Aug 28 18:56:04 EDT 2010
|
||||
@set LASTCHANGE Mon Sep 6 22:08:10 EDT 2010
|
||||
|
||||
@set EDITION 4.2
|
||||
@set VERSION 4.2
|
||||
@set UPDATED 28 August 2010
|
||||
@set UPDATED-MONTH August 2010
|
||||
@set UPDATED 6 September 2010
|
||||
@set UPDATED-MONTH September 2010
|
||||
|
||||
+9
-2
@@ -4523,11 +4523,18 @@ execute_builtin_or_function (words, builtin, var, redirects,
|
||||
and preserve the redirections. */
|
||||
if (builtin == command_builtin && this_shell_builtin == exec_builtin)
|
||||
{
|
||||
int discard;
|
||||
|
||||
discard = 0;
|
||||
if (saved_undo_list)
|
||||
dispose_redirects (saved_undo_list);
|
||||
{
|
||||
dispose_redirects (saved_undo_list);
|
||||
discard = 1;
|
||||
}
|
||||
redirection_undo_list = exec_redirection_undo_list;
|
||||
saved_undo_list = exec_redirection_undo_list = (REDIRECT *)NULL;
|
||||
discard_unwind_frame ("saved_redirects");
|
||||
if (discard)
|
||||
discard_unwind_frame ("saved redirects");
|
||||
}
|
||||
|
||||
if (saved_undo_list)
|
||||
|
||||
+11
-3
@@ -4081,7 +4081,7 @@ execute_builtin (builtin, words, flags, subshell)
|
||||
}
|
||||
|
||||
executing_builtin++;
|
||||
executing_command_builtin = builtin == command_builtin;
|
||||
executing_command_builtin |= builtin == command_builtin;
|
||||
result = ((*builtin) (words->next));
|
||||
|
||||
/* This shouldn't happen, but in case `return' comes back instead of
|
||||
@@ -4523,11 +4523,18 @@ execute_builtin_or_function (words, builtin, var, redirects,
|
||||
and preserve the redirections. */
|
||||
if (builtin == command_builtin && this_shell_builtin == exec_builtin)
|
||||
{
|
||||
int discard;
|
||||
|
||||
discard = 0;
|
||||
if (saved_undo_list)
|
||||
dispose_redirects (saved_undo_list);
|
||||
{
|
||||
dispose_redirects (saved_undo_list);
|
||||
discard = 1;
|
||||
}
|
||||
redirection_undo_list = exec_redirection_undo_list;
|
||||
saved_undo_list = exec_redirection_undo_list = (REDIRECT *)NULL;
|
||||
discard_unwind_frame ("saved_redirects");
|
||||
if (discard)
|
||||
discard_unwind_frame ("saved redirects");
|
||||
}
|
||||
|
||||
if (saved_undo_list)
|
||||
@@ -4929,6 +4936,7 @@ shell_execve (command, args, env)
|
||||
CHECK_TERMSIG;
|
||||
SETOSTYPE (1);
|
||||
|
||||
itrace("shell_execve: command = %s", command);
|
||||
/* If we get to this point, then start checking out the file.
|
||||
Maybe it is something we can hack ourselves. */
|
||||
if (i != ENOEXEC)
|
||||
|
||||
+1
-1
@@ -107,7 +107,7 @@
|
||||
#endif
|
||||
#ifndef UNCTRL
|
||||
/* control char to letter -- ASCII */
|
||||
# define UNCTRL(x) (TOUPPER((x) | 0x40))
|
||||
# define UNCTRL(x) (TOUPPER(x) ^ 0x40)
|
||||
#endif
|
||||
|
||||
#endif /* _SH_CHARTYPES_H */
|
||||
|
||||
@@ -171,6 +171,8 @@ ansicstr (string, len, flags, sawc, rlen)
|
||||
*rlen = r - ret;
|
||||
return ret;
|
||||
}
|
||||
else if ((flags & 1) == 0 && *s == 0)
|
||||
; /* pass \c through */
|
||||
else if ((flags & 1) == 0 && (c = *s))
|
||||
{
|
||||
s++;
|
||||
|
||||
@@ -1647,6 +1647,9 @@ typedef struct stream_saver {
|
||||
/* The globally known line number. */
|
||||
int line_number = 0;
|
||||
|
||||
/* The line number offset set by assigning to LINENO. Not currently used. */
|
||||
int line_number_base = 0;
|
||||
|
||||
#if defined (COND_COMMAND)
|
||||
static int cond_lineno;
|
||||
static int cond_token;
|
||||
@@ -3162,7 +3165,7 @@ parse_matched_pair (qc, open, close, lenp, flags)
|
||||
start_lineno = line_number;
|
||||
while (count)
|
||||
{
|
||||
ch = shell_getc (qc != '\'' && (tflags & LEX_PASSNEXT) == 0);
|
||||
ch = shell_getc (qc != '\'' && (tflags & (LEX_PASSNEXT)) == 0);
|
||||
|
||||
if (ch == EOF)
|
||||
{
|
||||
@@ -3431,7 +3434,7 @@ parse_comsub (qc, open, close, lenp, flags)
|
||||
while (count)
|
||||
{
|
||||
comsub_readchar:
|
||||
ch = shell_getc (qc != '\'' && (tflags & LEX_PASSNEXT) == 0);
|
||||
ch = shell_getc (qc != '\'' && (tflags & (LEX_INCOMMENT|LEX_PASSNEXT)) == 0);
|
||||
|
||||
if (ch == EOF)
|
||||
{
|
||||
|
||||
@@ -1647,6 +1647,9 @@ typedef struct stream_saver {
|
||||
/* The globally known line number. */
|
||||
int line_number = 0;
|
||||
|
||||
/* The line number offset set by assigning to LINENO. Not currently used. */
|
||||
int line_number_base = 0;
|
||||
|
||||
#if defined (COND_COMMAND)
|
||||
static int cond_lineno;
|
||||
static int cond_token;
|
||||
@@ -3162,7 +3165,7 @@ parse_matched_pair (qc, open, close, lenp, flags)
|
||||
start_lineno = line_number;
|
||||
while (count)
|
||||
{
|
||||
ch = shell_getc (qc != '\'' && (tflags & LEX_PASSNEXT) == 0);
|
||||
ch = shell_getc (qc != '\'' && (tflags & (LEX_PASSNEXT)) == 0);
|
||||
|
||||
if (ch == EOF)
|
||||
{
|
||||
@@ -4953,7 +4956,6 @@ prompt_again ()
|
||||
{
|
||||
char *temp_prompt;
|
||||
|
||||
itrace("prompt_again()");
|
||||
if (interactive == 0 || expanding_alias ()) /* XXX */
|
||||
return;
|
||||
|
||||
@@ -4988,7 +4990,6 @@ itrace("prompt_again()");
|
||||
FREE (current_decoded_prompt);
|
||||
current_decoded_prompt = temp_prompt;
|
||||
}
|
||||
itrace("prompt_again: current_prompt_string = %s", current_prompt_string);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -526,21 +526,20 @@ main (argc, argv, env)
|
||||
else
|
||||
init_noninteractive ();
|
||||
|
||||
#define CLOSE_FDS_AT_LOGIN
|
||||
#if defined (CLOSE_FDS_AT_LOGIN)
|
||||
/*
|
||||
* Some systems have the bad habit of starting login shells with lots of open
|
||||
* file descriptors. For instance, most systems that have picked up the
|
||||
* pre-4.0 Sun YP code leave a file descriptor open each time you call one
|
||||
* of the getpw* functions, and it's set to be open across execs. That
|
||||
* means one for login, one for xterm, one for shelltool, etc.
|
||||
* means one for login, one for xterm, one for shelltool, etc. There are
|
||||
* also systems that open persistent FDs to other agents or files as part
|
||||
* of process startup; these need to be set to be close-on-exec.
|
||||
*/
|
||||
if (login_shell && interactive_shell)
|
||||
{
|
||||
for (i = 3; i < 20; i++)
|
||||
close (i);
|
||||
SET_CLOSE_ON_EXEC (i);
|
||||
}
|
||||
#endif /* CLOSE_FDS_AT_LOGIN */
|
||||
|
||||
/* If we're in a strict Posix.2 mode, turn on interactive comments,
|
||||
alias expansion in non-interactive shells, and other Posix.2 things. */
|
||||
@@ -1293,12 +1292,13 @@ run_one_command (command)
|
||||
int code;
|
||||
|
||||
code = setjmp (top_level);
|
||||
|
||||
itrace("run_one_command: setjmp: code = %d", code);
|
||||
if (code != NOT_JUMPED)
|
||||
{
|
||||
#if defined (PROCESS_SUBSTITUTION)
|
||||
unlink_fifo_list ();
|
||||
#endif /* PROCESS_SUBSTITUTION */
|
||||
itrace("run_one_command: code = %d", code);
|
||||
switch (code)
|
||||
{
|
||||
/* Some kind of throw to top_level has occured. */
|
||||
|
||||
@@ -108,7 +108,7 @@ extern int errno;
|
||||
/* Evaluates to 1 if C is one of the shell's special parameters for which an
|
||||
indirect variable reference may be made. */
|
||||
#define VALID_INDIR_PARAM(c) \
|
||||
((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
|
||||
((posixly_correct == 0 && (c) == '#') || (posixly_correct == 0 && (c) == '?') || (c) == '@' || (c) == '*')
|
||||
|
||||
/* Evaluates to 1 if C is one of the OP characters that follows the parameter
|
||||
in ${parameter[:]OPword}. */
|
||||
@@ -1461,7 +1461,7 @@ extract_dollar_brace_string (string, sindex, quoted, flags)
|
||||
if (c == '\'')
|
||||
{
|
||||
/*itrace("extract_dollar_brace_string: c == single quote flags = %d quoted = %d dolbrace_state = %d", flags, quoted, dolbrace_state);*/
|
||||
if (posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE)
|
||||
if (posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
|
||||
ADVANCE_CHAR (string, slen, i);
|
||||
else
|
||||
{
|
||||
@@ -5907,7 +5907,7 @@ parameter_brace_expand_length (name)
|
||||
break;
|
||||
case '!':
|
||||
if (last_asynchronous_pid == NO_PID)
|
||||
t = (char *)NULL;
|
||||
t = (char *)NULL; /* XXX - error if set -u set? */
|
||||
else
|
||||
t = itos (last_asynchronous_pid);
|
||||
break;
|
||||
@@ -5929,6 +5929,8 @@ parameter_brace_expand_length (name)
|
||||
if (legal_number (name + 1, &arg_index)) /* ${#1} */
|
||||
{
|
||||
t = get_dollar_var_value (arg_index);
|
||||
if (t == 0 && unbound_vars_is_error)
|
||||
return INTMAX_MIN;
|
||||
number = MB_STRLEN (t);
|
||||
FREE (t);
|
||||
}
|
||||
@@ -5939,6 +5941,8 @@ parameter_brace_expand_length (name)
|
||||
t = assoc_reference (assoc_cell (var), "0");
|
||||
else
|
||||
t = array_reference (array_cell (var), 0);
|
||||
if (t == 0 && unbound_vars_is_error)
|
||||
return INTMAX_MIN;
|
||||
number = MB_STRLEN (t);
|
||||
}
|
||||
#endif
|
||||
@@ -6940,15 +6944,8 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
|
||||
/* If the name really consists of a special variable, then make sure
|
||||
that we have the entire name. We don't allow indirect references
|
||||
to special variables except `#', `?', `@' and `*'. */
|
||||
if ((sindex == t_index &&
|
||||
(string[t_index] == '-' ||
|
||||
string[t_index] == '?' ||
|
||||
string[t_index] == '#')) ||
|
||||
(sindex == t_index - 1 && string[sindex] == '!' &&
|
||||
(string[t_index] == '#' ||
|
||||
string[t_index] == '?' ||
|
||||
string[t_index] == '@' ||
|
||||
string[t_index] == '*')))
|
||||
if ((sindex == t_index && VALID_SPECIAL_LENGTH_PARAM (string[t_index])) ||
|
||||
(sindex == t_index - 1 && string[sindex] == '!' && VALID_INDIR_PARAM (string[t_index])))
|
||||
{
|
||||
t_index++;
|
||||
free (name);
|
||||
@@ -7043,6 +7040,13 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
|
||||
}
|
||||
|
||||
number = parameter_brace_expand_length (name);
|
||||
if (number == INTMAX_MIN && unbound_vars_is_error)
|
||||
{
|
||||
last_command_exit_value = EXECUTION_FAILURE;
|
||||
err_unboundvar (name+1);
|
||||
free (name);
|
||||
return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
|
||||
}
|
||||
free (name);
|
||||
|
||||
*indexp = sindex;
|
||||
@@ -7178,6 +7182,21 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
|
||||
|
||||
*indexp = sindex;
|
||||
|
||||
/* All the cases where an expansion can possibly generate an unbound
|
||||
variable error. */
|
||||
if (want_substring || want_patsub || want_casemod || c == '#' || c == '%' || c == RBRACE)
|
||||
{
|
||||
if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1]))
|
||||
{
|
||||
last_command_exit_value = EXECUTION_FAILURE;
|
||||
err_unboundvar (name);
|
||||
FREE (value);
|
||||
FREE (temp);
|
||||
free (name);
|
||||
return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is a substring spec, process it and add the result. */
|
||||
if (want_substring)
|
||||
{
|
||||
@@ -7251,15 +7270,6 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
|
||||
return &expand_wdesc_error;
|
||||
|
||||
case RBRACE:
|
||||
if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1]))
|
||||
{
|
||||
last_command_exit_value = EXECUTION_FAILURE;
|
||||
err_unboundvar (name);
|
||||
FREE (value);
|
||||
FREE (temp);
|
||||
free (name);
|
||||
return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
|
||||
}
|
||||
break;
|
||||
|
||||
case '#': /* ${param#[#]pattern} */
|
||||
@@ -9324,6 +9334,7 @@ expand_word_list_internal (list, eflags)
|
||||
if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
|
||||
{
|
||||
sh_wassign_func_t *assign_func;
|
||||
int is_special_builtin;
|
||||
|
||||
/* If the remainder of the words expand to nothing, Posix.2 requires
|
||||
that the variable and environment assignments affect the shell's
|
||||
@@ -9331,6 +9342,10 @@ expand_word_list_internal (list, eflags)
|
||||
assign_func = new_list ? assign_in_env : do_word_assignment;
|
||||
tempenv_assign_error = 0;
|
||||
|
||||
/* Posix says that special builtins exit if a variable assignment error
|
||||
occurs in an assignment preceding it. */
|
||||
is_special_builtin = (posixly_correct && new_list && find_special_builtin (new_list->word->word));
|
||||
|
||||
for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
|
||||
{
|
||||
this_command_name = (char *)NULL;
|
||||
@@ -9344,7 +9359,7 @@ expand_word_list_internal (list, eflags)
|
||||
if (assign_func == do_word_assignment)
|
||||
{
|
||||
last_command_exit_value = EXECUTION_FAILURE;
|
||||
if (interactive_shell == 0 && posixly_correct)
|
||||
if (interactive_shell == 0 && posixly_correct && is_special_builtin)
|
||||
exp_jump_to_top_level (FORCE_EOF);
|
||||
else
|
||||
exp_jump_to_top_level (DISCARD);
|
||||
|
||||
@@ -108,7 +108,7 @@ extern int errno;
|
||||
/* Evaluates to 1 if C is one of the shell's special parameters for which an
|
||||
indirect variable reference may be made. */
|
||||
#define VALID_INDIR_PARAM(c) \
|
||||
((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
|
||||
((posixly_correct == 0 && (c) == '#') || (posixly_correct == 0 && (c) == '?') || (c) == '@' || (c) == '*')
|
||||
|
||||
/* Evaluates to 1 if C is one of the OP characters that follows the parameter
|
||||
in ${parameter[:]OPword}. */
|
||||
@@ -1461,7 +1461,7 @@ extract_dollar_brace_string (string, sindex, quoted, flags)
|
||||
if (c == '\'')
|
||||
{
|
||||
/*itrace("extract_dollar_brace_string: c == single quote flags = %d quoted = %d dolbrace_state = %d", flags, quoted, dolbrace_state);*/
|
||||
if (posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE)
|
||||
if (posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
|
||||
ADVANCE_CHAR (string, slen, i);
|
||||
else
|
||||
{
|
||||
@@ -5929,6 +5929,8 @@ parameter_brace_expand_length (name)
|
||||
if (legal_number (name + 1, &arg_index)) /* ${#1} */
|
||||
{
|
||||
t = get_dollar_var_value (arg_index);
|
||||
if (t == 0 && unbound_vars_is_error)
|
||||
return INTMAX_MIN;
|
||||
number = MB_STRLEN (t);
|
||||
FREE (t);
|
||||
}
|
||||
@@ -5939,6 +5941,8 @@ parameter_brace_expand_length (name)
|
||||
t = assoc_reference (assoc_cell (var), "0");
|
||||
else
|
||||
t = array_reference (array_cell (var), 0);
|
||||
if (t == 0 && unbound_vars_is_error)
|
||||
return INTMAX_MIN;
|
||||
number = MB_STRLEN (t);
|
||||
}
|
||||
#endif
|
||||
@@ -6940,15 +6944,8 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
|
||||
/* If the name really consists of a special variable, then make sure
|
||||
that we have the entire name. We don't allow indirect references
|
||||
to special variables except `#', `?', `@' and `*'. */
|
||||
if ((sindex == t_index &&
|
||||
(string[t_index] == '-' ||
|
||||
string[t_index] == '?' ||
|
||||
string[t_index] == '#')) ||
|
||||
(sindex == t_index - 1 && string[sindex] == '!' &&
|
||||
(string[t_index] == '#' ||
|
||||
string[t_index] == '?' ||
|
||||
string[t_index] == '@' ||
|
||||
string[t_index] == '*')))
|
||||
if ((sindex == t_index && VALID_SPECIAL_LENGTH_PARAM (string[t_index])) ||
|
||||
(sindex == t_index - 1 && string[sindex] == '!' && VALID_INDIR_PARAM (string[t_index])))
|
||||
{
|
||||
t_index++;
|
||||
free (name);
|
||||
@@ -7043,6 +7040,13 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
|
||||
}
|
||||
|
||||
number = parameter_brace_expand_length (name);
|
||||
if (number == INTMAX_MIN && unbound_vars_is_error)
|
||||
{
|
||||
last_command_exit_value = EXECUTION_FAILURE;
|
||||
err_unboundvar (name+1);
|
||||
free (name);
|
||||
return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
|
||||
}
|
||||
free (name);
|
||||
|
||||
*indexp = sindex;
|
||||
@@ -7178,6 +7182,21 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
|
||||
|
||||
*indexp = sindex;
|
||||
|
||||
/* All the cases where an expansion can possibly generate an unbound
|
||||
variable error. */
|
||||
if (want_substring || want_patsub || want_casemod || c == '#' || c == '%' || c == RBRACE)
|
||||
{
|
||||
if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1]))
|
||||
{
|
||||
last_command_exit_value = EXECUTION_FAILURE;
|
||||
err_unboundvar (name);
|
||||
FREE (value);
|
||||
FREE (temp);
|
||||
free (name);
|
||||
return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is a substring spec, process it and add the result. */
|
||||
if (want_substring)
|
||||
{
|
||||
@@ -7251,15 +7270,6 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
|
||||
return &expand_wdesc_error;
|
||||
|
||||
case RBRACE:
|
||||
if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1]))
|
||||
{
|
||||
last_command_exit_value = EXECUTION_FAILURE;
|
||||
err_unboundvar (name);
|
||||
FREE (value);
|
||||
FREE (temp);
|
||||
free (name);
|
||||
return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
|
||||
}
|
||||
break;
|
||||
|
||||
case '#': /* ${param#[#]pattern} */
|
||||
@@ -7449,7 +7459,6 @@ param_expand (string, sindex, quoted, expanded_something,
|
||||
/* $? -- return value of the last synchronous command. */
|
||||
case '?':
|
||||
temp = itos (last_command_exit_value);
|
||||
itrace("last_command_exit_value = %d", last_command_exit_value);
|
||||
break;
|
||||
|
||||
/* $- -- flags supplied to the shell on invocation or by `set'. */
|
||||
@@ -9325,6 +9334,7 @@ expand_word_list_internal (list, eflags)
|
||||
if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
|
||||
{
|
||||
sh_wassign_func_t *assign_func;
|
||||
int is_special_builtin;
|
||||
|
||||
/* If the remainder of the words expand to nothing, Posix.2 requires
|
||||
that the variable and environment assignments affect the shell's
|
||||
@@ -9332,6 +9342,10 @@ expand_word_list_internal (list, eflags)
|
||||
assign_func = new_list ? assign_in_env : do_word_assignment;
|
||||
tempenv_assign_error = 0;
|
||||
|
||||
/* Posix says that special builtins exit if a variable assignment error
|
||||
occurs in an assignment preceding it. */
|
||||
is_special_builtin = (posixly_correct && new_list && find_special_builtin (new_list->word->word));
|
||||
|
||||
for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
|
||||
{
|
||||
this_command_name = (char *)NULL;
|
||||
@@ -9345,7 +9359,7 @@ expand_word_list_internal (list, eflags)
|
||||
if (assign_func == do_word_assignment)
|
||||
{
|
||||
last_command_exit_value = EXECUTION_FAILURE;
|
||||
if (interactive_shell == 0 && posixly_correct)
|
||||
if (interactive_shell == 0 && posixly_correct && is_special_builtin)
|
||||
exp_jump_to_top_level (FORCE_EOF);
|
||||
else
|
||||
exp_jump_to_top_level (DISCARD);
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
+2
-3
@@ -10,7 +10,7 @@ after exec1.sub without args: 0
|
||||
127
|
||||
/bin/sh: /bin/sh: cannot execute binary file
|
||||
126
|
||||
./execscript: line 39: /: is a directory
|
||||
./execscript: line 39: /: Is a directory
|
||||
126
|
||||
/: /: is a directory
|
||||
126
|
||||
@@ -20,8 +20,7 @@ after exec1.sub without args: 0
|
||||
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
|
||||
127
|
||||
./execscript: line 70: notthere: No such file or directory
|
||||
127
|
||||
./execscript: line 73: notthere: No such file or directory
|
||||
|
||||
@@ -112,3 +112,6 @@ ${THIS_SH} -i ./exec8.sub
|
||||
true | `echo true` &
|
||||
|
||||
echo after
|
||||
|
||||
# Problem with bash at least back to version 3.0
|
||||
${THIS_SH} -c 'VAR=0; VAR=1 command exec; exit ${VAR}'
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
export LC_ALL=C
|
||||
export LANG=C
|
||||
|
||||
if [ $UID -eq 0 ]; then
|
||||
echo "execscript: the test suite should not be run as root" >&2
|
||||
fi
|
||||
|
||||
set -- one two three
|
||||
echo before exec1.sub: "$@"
|
||||
echo calling exec1.sub
|
||||
./exec1.sub aa bb cc dd ee
|
||||
echo after exec1.sub with args: $?
|
||||
./exec1.sub
|
||||
echo after exec1.sub without args: $?
|
||||
|
||||
# set up a fixed path so we know notthere will not be found
|
||||
PATH=/usr/bin:/bin:/usr/local/bin:
|
||||
export PATH
|
||||
|
||||
notthere
|
||||
echo $?
|
||||
|
||||
# this is iffy, since the error messages may vary from system to system
|
||||
# and /tmp might not exist
|
||||
ln -s ${THIS_SH} /tmp/bash 2>/dev/null
|
||||
if [ -f /tmp/bash ]; then
|
||||
/tmp/bash notthere
|
||||
else
|
||||
${THIS_SH} notthere
|
||||
fi
|
||||
echo $?
|
||||
rm -f /tmp/bash
|
||||
|
||||
# /bin/sh should be there on all systems
|
||||
${THIS_SH} /bin/sh
|
||||
echo $?
|
||||
|
||||
# try executing a directory
|
||||
/
|
||||
echo $?
|
||||
|
||||
${THIS_SH} /
|
||||
echo $?
|
||||
|
||||
# try sourcing a directory
|
||||
. /
|
||||
echo $?
|
||||
|
||||
# try sourcing a binary file -- post-2.04 versions don't do the binary file
|
||||
# check, and will probably fail with `command not found', or status 127
|
||||
# bash-4.1 and later check for 256 NUL characters and fail as binary files
|
||||
# if there are more than that, it's probably binary
|
||||
. ${THIS_SH} 2>/dev/null
|
||||
echo $?
|
||||
|
||||
# post-bash-2.05 versions allow sourcing non-regular files
|
||||
. /dev/null
|
||||
echo $?
|
||||
|
||||
# kill two birds with one test -- test out the BASH_ENV code
|
||||
echo echo this is bashenv > /tmp/bashenv
|
||||
export BASH_ENV=/tmp/bashenv
|
||||
${THIS_SH} ./exec3.sub
|
||||
rm -f /tmp/bashenv
|
||||
unset BASH_ENV
|
||||
|
||||
# we're resetting the $PATH to empty, so this should be last
|
||||
PATH=
|
||||
|
||||
notthere
|
||||
echo $?
|
||||
|
||||
command notthere
|
||||
echo $?
|
||||
|
||||
command -p notthere
|
||||
echo $?
|
||||
|
||||
# but -p should guarantee that we find all the standard utilities, even
|
||||
# with an empty or unset $PATH
|
||||
command -p sh -c 'echo this is $0'
|
||||
unset PATH
|
||||
command -p sh -c 'echo this is $0'
|
||||
|
||||
# a bug in bash before bash-2.01 caused PATH to be set to the empty string
|
||||
# when command -p was run with PATH unset
|
||||
echo ${PATH-unset}
|
||||
|
||||
echo "echo ok" | ${THIS_SH} -t
|
||||
|
||||
${THIS_SH} ./exec2.sub
|
||||
echo $?
|
||||
|
||||
${THIS_SH} ./exec4.sub
|
||||
|
||||
# try exec'ing a command that cannot be found in $PATH
|
||||
${THIS_SH} ./exec5.sub
|
||||
|
||||
# this was a bug in bash versions before bash-2.04
|
||||
${THIS_SH} -c 'cat </dev/null | cat >/dev/null' >&-
|
||||
|
||||
# checks for proper return values in subshell commands with inverted return
|
||||
# values
|
||||
|
||||
${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
|
||||
|
||||
${THIS_SH} -c 'VAR=0; VAR=1 command exec; exit ${VAR}'
|
||||
@@ -35,7 +35,7 @@ argv[1] = <x'>
|
||||
<x> <.> <w> <.> <x> <.> <w> <.>
|
||||
argv[1] = <'bar>
|
||||
argv[1] = <foo 'bar baz>
|
||||
argv[1] = <z}>
|
||||
argv[1] = <}z>
|
||||
argv[1] = <''z}>
|
||||
./posixexp.tests: line 68: unexpected EOF while looking for matching `}'
|
||||
./posixexp.tests: line 69: syntax error: unexpected end of file
|
||||
|
||||
+29
-1
@@ -240,18 +240,24 @@ unwind_frame_discard_internal (tag, ignore)
|
||||
char *tag, *ignore;
|
||||
{
|
||||
UNWIND_ELT *elt;
|
||||
int found;
|
||||
|
||||
found = 0;
|
||||
while (elt = unwind_protect_list)
|
||||
{
|
||||
unwind_protect_list = unwind_protect_list->head.next;
|
||||
if (elt->head.cleanup == 0 && (STREQ (elt->arg.v, tag)))
|
||||
{
|
||||
uwpfree (elt);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
uwpfree (elt);
|
||||
}
|
||||
|
||||
if (found == 0)
|
||||
internal_warning ("unwind_frame_discard: %s: frame not found", tag);
|
||||
}
|
||||
|
||||
/* Restore the value of a variable, based on the contents of SV.
|
||||
@@ -269,17 +275,20 @@ unwind_frame_run_internal (tag, ignore)
|
||||
char *tag, *ignore;
|
||||
{
|
||||
UNWIND_ELT *elt;
|
||||
int found;
|
||||
|
||||
found = 0;
|
||||
while (elt = unwind_protect_list)
|
||||
{
|
||||
unwind_protect_list = elt->head.next;
|
||||
|
||||
/* If tag, then compare. */
|
||||
if (!elt->head.cleanup)
|
||||
if (elt->head.cleanup == 0)
|
||||
{
|
||||
if (tag && STREQ (elt->arg.v, tag))
|
||||
{
|
||||
uwpfree (elt);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -293,6 +302,8 @@ unwind_frame_run_internal (tag, ignore)
|
||||
|
||||
uwpfree (elt);
|
||||
}
|
||||
if (tag && found == 0)
|
||||
internal_warning ("unwind_frame_run: %s: frame not found", tag);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -324,3 +335,20 @@ unwind_protect_mem (var, size)
|
||||
{
|
||||
without_interrupts (unwind_protect_mem_internal, var, (char *) &size);
|
||||
}
|
||||
|
||||
#if defined (DEBUG)
|
||||
void
|
||||
print_unwind_protect_tags ()
|
||||
{
|
||||
UNWIND_ELT *elt;
|
||||
|
||||
elt = unwind_protect_list;
|
||||
while (elt)
|
||||
{
|
||||
unwind_protect_list = unwind_protect_list->head.next;
|
||||
if (elt->head.cleanup == 0)
|
||||
fprintf(stderr, "tag: %s\n", elt->arg.v);
|
||||
elt = unwind_protect_list;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
+354
@@ -0,0 +1,354 @@
|
||||
/* unwind_prot.c - a simple unwind-protect system for internal variables */
|
||||
|
||||
/* I can't stand it anymore! Please can't we just write the
|
||||
whole Unix system in lisp or something? */
|
||||
|
||||
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Unwind Protection Scheme for Bash */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
#include "config.h"
|
||||
|
||||
#include "bashtypes.h"
|
||||
#include "bashansi.h"
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <stddef.h>
|
||||
#endif
|
||||
|
||||
#ifndef offsetof
|
||||
# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||
#endif
|
||||
|
||||
#include "command.h"
|
||||
#include "general.h"
|
||||
#include "unwind_prot.h"
|
||||
#include "quit.h"
|
||||
#include "sig.h"
|
||||
|
||||
/* Structure describing a saved variable and the value to restore it to. */
|
||||
typedef struct {
|
||||
char *variable;
|
||||
int size;
|
||||
char desired_setting[1]; /* actual size is `size' */
|
||||
} SAVED_VAR;
|
||||
|
||||
/* If HEAD.CLEANUP is null, then ARG.V contains a tag to throw back to.
|
||||
If HEAD.CLEANUP is restore_variable, then SV.V contains the saved
|
||||
variable. Otherwise, call HEAD.CLEANUP (ARG.V) to clean up. */
|
||||
typedef union uwp {
|
||||
struct uwp_head {
|
||||
union uwp *next;
|
||||
Function *cleanup;
|
||||
} head;
|
||||
struct {
|
||||
struct uwp_head uwp_head;
|
||||
char *v;
|
||||
} arg;
|
||||
struct {
|
||||
struct uwp_head uwp_head;
|
||||
SAVED_VAR v;
|
||||
} sv;
|
||||
} UNWIND_ELT;
|
||||
|
||||
|
||||
static void without_interrupts __P((VFunction *, char *, char *));
|
||||
static void unwind_frame_discard_internal __P((char *, char *));
|
||||
static void unwind_frame_run_internal __P((char *, char *));
|
||||
static void add_unwind_protect_internal __P((Function *, char *));
|
||||
static void remove_unwind_protect_internal __P((char *, char *));
|
||||
static void run_unwind_protects_internal __P((char *, char *));
|
||||
static void clear_unwind_protects_internal __P((char *, char *));
|
||||
static inline void restore_variable __P((SAVED_VAR *));
|
||||
static void unwind_protect_mem_internal __P((char *, char *));
|
||||
|
||||
static UNWIND_ELT *unwind_protect_list = (UNWIND_ELT *)NULL;
|
||||
|
||||
#define uwpalloc(elt) (elt) = (UNWIND_ELT *)xmalloc (sizeof (UNWIND_ELT))
|
||||
#define uwpfree(elt) free(elt)
|
||||
|
||||
/* Run a function without interrupts. This relies on the fact that the
|
||||
FUNCTION cannot change the value of interrupt_immediately. (I.e., does
|
||||
not call QUIT (). */
|
||||
static void
|
||||
without_interrupts (function, arg1, arg2)
|
||||
VFunction *function;
|
||||
char *arg1, *arg2;
|
||||
{
|
||||
int old_interrupt_immediately;
|
||||
|
||||
old_interrupt_immediately = interrupt_immediately;
|
||||
interrupt_immediately = 0;
|
||||
|
||||
(*function)(arg1, arg2);
|
||||
|
||||
interrupt_immediately = old_interrupt_immediately;
|
||||
}
|
||||
|
||||
/* Start the beginning of a region. */
|
||||
void
|
||||
begin_unwind_frame (tag)
|
||||
char *tag;
|
||||
{
|
||||
add_unwind_protect ((Function *)NULL, tag);
|
||||
}
|
||||
|
||||
/* Discard the unwind protects back to TAG. */
|
||||
void
|
||||
discard_unwind_frame (tag)
|
||||
char *tag;
|
||||
{
|
||||
if (unwind_protect_list)
|
||||
without_interrupts (unwind_frame_discard_internal, tag, (char *)NULL);
|
||||
}
|
||||
|
||||
/* Run the unwind protects back to TAG. */
|
||||
void
|
||||
run_unwind_frame (tag)
|
||||
char *tag;
|
||||
{
|
||||
if (unwind_protect_list)
|
||||
without_interrupts (unwind_frame_run_internal, tag, (char *)NULL);
|
||||
}
|
||||
|
||||
/* Add the function CLEANUP with ARG to the list of unwindable things. */
|
||||
void
|
||||
add_unwind_protect (cleanup, arg)
|
||||
Function *cleanup;
|
||||
char *arg;
|
||||
{
|
||||
without_interrupts (add_unwind_protect_internal, (char *)cleanup, arg);
|
||||
}
|
||||
|
||||
/* Remove the top unwind protect from the list. */
|
||||
void
|
||||
remove_unwind_protect ()
|
||||
{
|
||||
if (unwind_protect_list)
|
||||
without_interrupts
|
||||
(remove_unwind_protect_internal, (char *)NULL, (char *)NULL);
|
||||
}
|
||||
|
||||
/* Run the list of cleanup functions in unwind_protect_list. */
|
||||
void
|
||||
run_unwind_protects ()
|
||||
{
|
||||
if (unwind_protect_list)
|
||||
without_interrupts
|
||||
(run_unwind_protects_internal, (char *)NULL, (char *)NULL);
|
||||
}
|
||||
|
||||
/* Erase the unwind-protect list. If flags is 1, free the elements. */
|
||||
void
|
||||
clear_unwind_protect_list (flags)
|
||||
int flags;
|
||||
{
|
||||
char *flag;
|
||||
|
||||
if (unwind_protect_list)
|
||||
{
|
||||
flag = flags ? "" : (char *)NULL;
|
||||
without_interrupts
|
||||
(clear_unwind_protects_internal, flag, (char *)NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
have_unwind_protects ()
|
||||
{
|
||||
return (unwind_protect_list != 0);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* The Actual Functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
static void
|
||||
add_unwind_protect_internal (cleanup, arg)
|
||||
Function *cleanup;
|
||||
char *arg;
|
||||
{
|
||||
UNWIND_ELT *elt;
|
||||
|
||||
uwpalloc (elt);
|
||||
elt->head.next = unwind_protect_list;
|
||||
elt->head.cleanup = cleanup;
|
||||
elt->arg.v = arg;
|
||||
unwind_protect_list = elt;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_unwind_protect_internal (ignore1, ignore2)
|
||||
char *ignore1, *ignore2;
|
||||
{
|
||||
UNWIND_ELT *elt;
|
||||
|
||||
elt = unwind_protect_list;
|
||||
if (elt)
|
||||
{
|
||||
unwind_protect_list = unwind_protect_list->head.next;
|
||||
uwpfree (elt);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
run_unwind_protects_internal (ignore1, ignore2)
|
||||
char *ignore1, *ignore2;
|
||||
{
|
||||
unwind_frame_run_internal ((char *) NULL, (char *) NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
clear_unwind_protects_internal (flag, ignore)
|
||||
char *flag, *ignore;
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
while (unwind_protect_list)
|
||||
remove_unwind_protect_internal ((char *)NULL, (char *)NULL);
|
||||
}
|
||||
unwind_protect_list = (UNWIND_ELT *)NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
unwind_frame_discard_internal (tag, ignore)
|
||||
char *tag, *ignore;
|
||||
{
|
||||
UNWIND_ELT *elt;
|
||||
int found;
|
||||
|
||||
found = 0;
|
||||
while (elt = unwind_protect_list)
|
||||
{
|
||||
unwind_protect_list = unwind_protect_list->head.next;
|
||||
if (elt->head.cleanup == 0 && (STREQ (elt->arg.v, tag)))
|
||||
{
|
||||
uwpfree (elt);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
uwpfree (elt);
|
||||
}
|
||||
|
||||
if (found == 0)
|
||||
internal_warning ("unwind_frame_discard: %s: frame not found", tag);
|
||||
}
|
||||
|
||||
/* Restore the value of a variable, based on the contents of SV.
|
||||
sv->desired_setting is a block of memory SIZE bytes long holding the
|
||||
value itself. This block of memory is copied back into the variable. */
|
||||
static inline void
|
||||
restore_variable (sv)
|
||||
SAVED_VAR *sv;
|
||||
{
|
||||
FASTCOPY (sv->desired_setting, sv->variable, sv->size);
|
||||
}
|
||||
|
||||
static void
|
||||
unwind_frame_run_internal (tag, ignore)
|
||||
char *tag, *ignore;
|
||||
{
|
||||
UNWIND_ELT *elt;
|
||||
int found;
|
||||
|
||||
found = 0;
|
||||
while (elt = unwind_protect_list)
|
||||
{
|
||||
unwind_protect_list = elt->head.next;
|
||||
|
||||
/* If tag, then compare. */
|
||||
if (elt->head.cleanup == 0)
|
||||
{
|
||||
if (tag && STREQ (elt->arg.v, tag))
|
||||
{
|
||||
uwpfree (elt);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (elt->head.cleanup == (Function *) restore_variable)
|
||||
restore_variable (&elt->sv.v);
|
||||
else
|
||||
(*(elt->head.cleanup)) (elt->arg.v);
|
||||
}
|
||||
|
||||
uwpfree (elt);
|
||||
}
|
||||
if (found == 0)
|
||||
internal_warning ("unwind_frame_run: %s: frame not found", tag);
|
||||
}
|
||||
|
||||
static void
|
||||
unwind_protect_mem_internal (var, psize)
|
||||
char *var;
|
||||
char *psize;
|
||||
{
|
||||
int size, allocated;
|
||||
UNWIND_ELT *elt;
|
||||
|
||||
size = *(int *) psize;
|
||||
allocated = size + offsetof (UNWIND_ELT, sv.v.desired_setting[0]);
|
||||
elt = (UNWIND_ELT *)xmalloc (allocated);
|
||||
elt->head.next = unwind_protect_list;
|
||||
elt->head.cleanup = (Function *) restore_variable;
|
||||
elt->sv.v.variable = var;
|
||||
elt->sv.v.size = size;
|
||||
FASTCOPY (var, elt->sv.v.desired_setting, size);
|
||||
unwind_protect_list = elt;
|
||||
}
|
||||
|
||||
/* Save the value of a variable so it will be restored when unwind-protects
|
||||
are run. VAR is a pointer to the variable. SIZE is the size in
|
||||
bytes of VAR. */
|
||||
void
|
||||
unwind_protect_mem (var, size)
|
||||
char *var;
|
||||
int size;
|
||||
{
|
||||
without_interrupts (unwind_protect_mem_internal, var, (char *) &size);
|
||||
}
|
||||
|
||||
#if defined (DEBUG)
|
||||
void
|
||||
print_unwind_protect_tags ()
|
||||
{
|
||||
UNWIND_ELT *elt;
|
||||
|
||||
elt = unwind_protect_list;
|
||||
while (elt)
|
||||
{
|
||||
unwind_protect_list = unwind_protect_list->head.next;
|
||||
if (elt->head.cleanup == 0)
|
||||
fprintf(stderr, "tag: %s\n", elt->arg.v);
|
||||
elt = unwind_protect_list;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+2
-2
@@ -83,7 +83,7 @@ extern char **environ;
|
||||
|
||||
/* Variables used here and defined in other files. */
|
||||
extern int posixly_correct;
|
||||
extern int line_number;
|
||||
extern int line_number, line_number_base;
|
||||
extern int subshell_environment, indirection_level, subshell_level;
|
||||
extern int build_version, patch_level;
|
||||
extern int expanding_redir;
|
||||
@@ -1336,7 +1336,7 @@ assign_lineno (var, value, unused, key)
|
||||
|
||||
if (value == 0 || *value == '\0' || legal_number (value, &new_value) == 0)
|
||||
new_value = 0;
|
||||
line_number = new_value;
|
||||
line_number = line_number_base = new_value;
|
||||
return var;
|
||||
}
|
||||
|
||||
|
||||
+10
-8
@@ -387,11 +387,14 @@ initialize_shell_variables (env, privmode)
|
||||
#endif
|
||||
{
|
||||
temp_var = bind_variable (name, string, 0);
|
||||
if (legal_identifier (name))
|
||||
VSETATTR (temp_var, (att_exported | att_imported));
|
||||
else
|
||||
VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
|
||||
array_needs_making = 1;
|
||||
if (temp_var)
|
||||
{
|
||||
if (legal_identifier (name))
|
||||
VSETATTR (temp_var, (att_exported | att_imported));
|
||||
else
|
||||
VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
|
||||
array_needs_making = 1;
|
||||
}
|
||||
}
|
||||
|
||||
name[char_index] = '=';
|
||||
@@ -2389,7 +2392,7 @@ bind_int_variable (lhs, rhs)
|
||||
#endif
|
||||
v = bind_variable (lhs, rhs, 0);
|
||||
|
||||
if (isint)
|
||||
if (v && isint)
|
||||
VSETATTR (v, att_integer);
|
||||
|
||||
return (v);
|
||||
@@ -2838,7 +2841,7 @@ delete_all_variables (hashed_vars)
|
||||
if (!entry) \
|
||||
{ \
|
||||
entry = bind_variable (name, "", 0); \
|
||||
if (!no_invisible_vars) entry->attributes |= att_invisible; \
|
||||
if (!no_invisible_vars && entry) entry->attributes |= att_invisible; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
@@ -4733,7 +4736,6 @@ sv_xtracefd (name)
|
||||
int fd;
|
||||
FILE *fp;
|
||||
|
||||
itrace("sv_xtracefd: %s", name);
|
||||
v = find_variable (name);
|
||||
if (v == 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user