declaration builtin
subst.c
+ - do_assignment_internal: explicitly handle case where we are
+ executing in a function and we want to create a global array or
+ assoc variable
- shell_expand_word_list: call make_internal_declare if -a option
given to declaration builtin (W_ASSIGNARRAY); handle -g option with
it (W_ASSNGLOBAL). Fixes inconsistency noticed by Vicente Couce
{execute_cmd,subst,variables}.c
- removed all code that mentioned W_GLOBEXP
- removed mention of gnu_argv_flags and code that set it
+
+ 1/22
+ ----
+subst.c
+ - param_expand: set W_SPLITSPACE if we expand (unquoted) $* and
+ IFS is unset or null so we can be sure to split this on spaces
+ no matter what happens with IFS later
+ - expand_word_internal: note that param_expand returns W_SPLITSPACE
+ in the returned word flags and keep track of that state with
+ `split_on_spaces'
+
+ 1/23
+ ----
+subst.c
+ - expand_word_internal: if split_on_spaces is non-zero, make sure
+ we split `istring' on spaces and return the resultant word. The
+ previous expansions should have quoted spaces in the positional
+ parameters where necessary. Suggested by Dan Douglas
+ <ormaaj@gmail.com>
+
+execute_cmd.c
+ - execute_command_internal: make sure any subshell forked to run a
+ group command or user subshell at the end of a pipeline runs any
+ EXIT trap it sets. Fixes debian bash bug 698411
+ http://bugs.debian.org/cgi-big/bugreport.cgi?bug=698411
+
+subst.c
+ - shell_expand_word_list: fix code that creates args for and calls
+ make_internal_declare to avoid calling it twice (missing `else'
+ in 12/26 change)
+ - do_assignment_internal: fix code from 12/26 change to fix problem
+ where an existing assoc variable could be converted to an array
+ without checking `mkassoc'
+
+ 1/24
+ ----
+builtins/evalfile.c
+ - _evalfile: add missing `close (fd)' calls before returning to
+ avoid fd leaks. Bug and fix from Roman Rakus <rrakus@redhat.com>
+
+ 1/25
+ ----
+builtins/read.def
+ - read_builtin: don't try to play tricks with the top of the unwind-
+ protect stack after read gets a SIGALRM; save input_string to new
+ memory, run the stack, then restore input_string and assign the
+ variables. Part of fix for bug reported by konsolebox
+ <konsolebox@gmail.com>; the rest of the fix is with the changes in
+ trap and signal handling and doing away with interrupt_immediately
+
+ 1/26
+ ----
+redir.c
+ - redirection_expand, write_here_string, write_here_document: before
+ calling any of the word expansion functions, after setting
+ expanding_redir to 1 (which bypasses the temp environment in the
+ variable lookup functions), call sv_ifs to reset the cached IFS-
+ related variables set by subst.c:setifs(). This ensures that
+ redirections will not get any IFS values that are set in the
+ temporary environment, as Posix specifies. Then, after the word
+ expansions, after resetting expanding_redir to 0, call sv_ifs
+ again to make sure the cached IFS values are set from any
+ assignments in the temporary environment. We force executing_builtin
+ to 1 to `fool' the variable lookup functions into using any temp
+ environment, then reset it to its old value after sv_ifs returns.
+ This is what allows read() to use the (cached) IFS variables set
+ in the temp environment. Fixes inconsistency reported by Dan Douglas
+ <ormaaj@gmail.com>
declaration builtin
subst.c
+ - do_assignment_internal: explicitly handle case where we are
+ executing in a function and we want to create a global array or
+ assoc variable
- shell_expand_word_list: call make_internal_declare if -a option
given to declaration builtin (W_ASSIGNARRAY); handle -g option with
it (W_ASSNGLOBAL). Fixes inconsistency noticed by Vicente Couce
Suggested by Dan Douglas <ormaaj@gmail.com> [TENTATIVE, needs work
on IFS side effects]
-command.h,subst.c
+command.h
- W_GLOBEXP (which was unused) is now W_SPLITSPACE (which isn't used
- yet), removed all code that mentioned W_GLOBEXP
+ yet)
{execute_cmd,subst,variables}.c
- - removed mention of gnu_argv_flags
+ - removed all code that mentioned W_GLOBEXP
+ - removed mention of gnu_argv_flags and code that set it
+
+ 1/22
+ ----
+subst.c
+ - param_expand: set W_SPLITSPACE if we expand (unquoted) $* and
+ IFS is unset or null so we can be sure to split this on spaces
+ no matter what happens with IFS later
+ - expand_word_internal: note that param_expand returns W_SPLITSPACE
+ in the returned word flags and keep track of that state with
+ `split_on_spaces'
+
+ 1/23
+ ----
+subst.c
+ - expand_word_internal: if split_on_spaces is non-zero, make sure
+ we split `istring' on spaces and return the resultant word. The
+ previous expansions should have quoted spaces in the positional
+ parameters where necessary. Suggested by Dan Douglas
+ <ormaaj@gmail.com>
+
+execute_cmd.c
+ - execute_command_internal: make sure any subshell forked to run a
+ group command or user subshell at the end of a pipeline runs any
+ EXIT trap it sets. Fixes debian bash bug 698411
+ http://bugs.debian.org/cgi-big/bugreport.cgi?bug=698411
+
+subst.c
+ - shell_expand_word_list: fix code that creates args for and calls
+ make_internal_declare to avoid calling it twice (missing `else'
+ in 12/26 change)
+ - do_assignment_internal: fix code from 12/26 change to fix problem
+ where an existing assoc variable could be converted to an array
+ without checking `mkassoc'
+
+ 1/24
+ ----
+builtins/evalfile.c
+ - _evalfile: add missing `close (fd)' calls before returning to
+ avoid fd leaks. Bug and fix from Roman Rakus <rrakus@redhat.com>
+
+ 1/25
+ ----
+builtins/read.def
+ - read_builtin: don't try to play tricks with the top of the unwind-
+ protect stack after read gets a SIGALRM; save input_string to new
+ memory, run the stack, then restore input_string and assign the
+ variables. Part of fix for bug reported by konsolebox
+ <konsolebox@gmail.com>; the rest of the fix is with the changes in
+ trap and signal handling and doing away with interrupt_immediately
tests/dollar-star4.sub f
tests/dollar-star5.sub f
tests/dollar-star6.sub f
+tests/dollar-star7.sub f
tests/dollar.right f
tests/dstack.tests f
tests/dstack.right f
tests/trap2.sub f 755
tests/trap2a.sub f 755
tests/trap3.sub f
+tests/trap4.sub f
tests/type.tests f
tests/type.right f
tests/type1.sub f
tests/varenv2.sub f
tests/varenv3.sub f
tests/varenv4.sub f
+tests/varenv5.sub f
tests/version f
tests/version.mini f
tests/vredir.tests f
if (fd < 0 || (fstat (fd, &finfo) == -1))
{
+ i = errno;
+ if (fd >= 0)
+ close (fd);
+ errno = i;
+
file_error_and_exit:
if (((flags & FEVAL_ENOENTOK) == 0) || errno != ENOENT)
file_error (filename);
if (S_ISDIR (finfo.st_mode))
{
(*errfunc) (_("%s: is a directory"), filename);
+ close (fd);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
}
else if ((flags & FEVAL_REGFILE) && S_ISREG (finfo.st_mode) == 0)
{
(*errfunc) (_("%s: not a regular file"), filename);
+ close (fd);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
}
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
(*errfunc) (_("%s: file is too large"), filename);
+ close (fd);
return ((flags & FEVAL_BUILTIN) ? EXECUTION_FAILURE : -1);
}
sigalrm_seen = 0;
/* Tricky. The top of the unwind-protect stack is the free of
input_string. We want to run all the rest and use input_string,
- so we have to remove it from the stack. */
+ so we have to save input_string temporarily, run the unwind-
+ protects, then restore input_string so we can use it later */
orig_input_string = 0;
+ input_string[i] = '\0'; /* make sure it's terminated */
+ if (i == 0)
+ {
+ t = (char *)xmalloc (1);
+ t[0] = 0;
+ }
+ else
+ t = savestring (input_string);
- remove_unwind_protect ();
run_unwind_frame ("read_builtin");
- input_string[i] = '\0'; /* make sure it's terminated */
+ input_string = t;
retval = 128+SIGALRM;
goto assign_vars;
}
COMMAND struct. Need to keep in mind that execute_in_subshell
runs the exit trap for () subshells itself. */
s = user_subshell == 0 && command->type == cm_group && pipe_in == NO_PIPE && pipe_out == NO_PIPE && asynchronous;
+ /* run exit trap for : | { ...; } and : | ( ... ) */
+ s += user_subshell == 0 && command->type == cm_group && pipe_in != NO_PIPE && pipe_out == NO_PIPE && asynchronous == 0;
last_command_exit_value = execute_in_subshell (command, asynchronous, pipe_in, pipe_out, fds_to_close);
if (s)
WAIT status;
PROCESS *child;
pid_t pid;
+
int call_set_current, last_stopped_job, job, children_exited, waitpid_flags;
static int wcontinued = WCONTINUED; /* run-time fix for glibc problem */
: 0;
if (sigchld || block == 0)
waitpid_flags |= WNOHANG;
+
/* Check for terminating signals and exit the shell if we receive one */
CHECK_TERMSIG;
-
/* Check for a trapped signal interrupting the wait builtin and jump out */
CHECK_WAIT_INTR;
}
#ifdef DEBUG
+# if 0
if (ndeadproc != js.c_reaped)
itrace("mark_dead_jobs_as_notified: ndeadproc (%d) != js.c_reaped (%d)", ndeadproc, js.c_reaped);
+# endif
if (ndead != js.j_ndead)
itrace("mark_dead_jobs_as_notified: ndead (%d) != js.j_ndead (%d)", ndead, js.j_ndead);
#endif
ssize_t r;
while ((r = read (fd, buf, len)) < 0 && errno == EINTR)
- check_signals_and_traps (); /* XXX */
+ check_signals_and_traps (); /* XXX - should it be check_signals()? */
return r;
}
extern int posixly_correct;
extern int last_command_exit_value;
+extern int executing_builtin;
extern REDIRECT *redirection_undo_list;
extern REDIRECT *exec_redirection_undo_list;
char *result;
WORD_LIST *tlist1, *tlist2;
WORD_DESC *w;
+ int old;
w = copy_word (word);
if (posixly_correct)
tlist1 = make_word_list (w, (WORD_LIST *)NULL);
expanding_redir = 1;
+ /* Now that we've changed the variable search order to ignore the temp
+ environment, see if we need to change the cached IFS values. */
+ sv_ifs ("IFS");
tlist2 = expand_words_no_vars (tlist1);
expanding_redir = 0;
+ /* Now we need to change the variable search order back to include the temp
+ environment. We force the temp environment search by forcing
+ executing_builtin to 1. This is what makes `read' get the right values
+ for the IFS-related cached variables, for example. */
+ old = executing_builtin;
+ executing_builtin = 1;
+ sv_ifs ("IFS");
+ executing_builtin = old;
dispose_words (tlist1);
- if (!tlist2 || tlist2->next)
+ if (tlist2 == 0 || tlist2->next)
{
/* We expanded to no words, or to more than a single word.
Dispose of the word list and return NULL. */
WORD_DESC *redirectee;
{
char *herestr;
- int herelen, n, e;
+ int herelen, n, e, old;
expanding_redir = 1;
+ /* Now that we've changed the variable search order to ignore the temp
+ environment, see if we need to change the cached IFS values. */
+ sv_ifs ("IFS");
herestr = expand_string_to_string (redirectee->word, 0);
expanding_redir = 0;
+ /* Now we need to change the variable search order back to include the temp
+ environment. We force the temp environment search by forcing
+ executing_builtin to 1. This is what makes `read' get the right values
+ for the IFS-related cached variables, for example. */
+ old = executing_builtin;
+ executing_builtin = 1;
+ sv_ifs ("IFS");
+ executing_builtin = old;
+
herelen = STRLEN (herestr);
n = write (fd, herestr, herelen);
WORD_DESC *redirectee;
{
char *document;
- int document_len, fd2;
+ int document_len, fd2, old;
FILE *fp;
register WORD_LIST *t, *tlist;
}
expanding_redir = 1;
+ /* Now that we've changed the variable search order to ignore the temp
+ environment, see if we need to change the cached IFS values. */
+ sv_ifs ("IFS");
tlist = expand_string (redirectee->word, Q_HERE_DOCUMENT);
expanding_redir = 0;
+ /* Now we need to change the variable search order back to include the temp
+ environment. We force the temp environment search by forcing
+ executing_builtin to 1. This is what makes `read' get the right values
+ for the IFS-related cached variables, for example. */
+ old = executing_builtin;
+ executing_builtin = 1;
+ sv_ifs ("IFS");
+ executing_builtin = old;
if (tlist)
{
extern int posixly_correct;
extern int last_command_exit_value;
+extern int executing_builtin;
extern REDIRECT *redirection_undo_list;
extern REDIRECT *exec_redirection_undo_list;
else if (expandable_redirection_filename (temp))
{
expandable_filename:
+ oflags = temp->redirectee.filename->flags;
if (posixly_correct && interactive_shell == 0)
- {
- oflags = temp->redirectee.filename->flags;
- temp->redirectee.filename->flags |= W_NOGLOB;
- }
+ temp->redirectee.filename->flags |= W_NOGLOB;
+ temp->redirectee.filename->flags |= W_NOCOMSUB;
filename = allocname = redirection_expand (temp->redirectee.filename);
- if (posixly_correct && interactive_shell == 0)
- temp->redirectee.filename->flags = oflags;
+ temp->redirectee.filename->flags = oflags;
if (filename == 0)
filename = temp->redirectee.filename->word;
}
char *result;
WORD_LIST *tlist1, *tlist2;
WORD_DESC *w;
+ int old;
w = copy_word (word);
if (posixly_correct)
tlist1 = make_word_list (w, (WORD_LIST *)NULL);
expanding_redir = 1;
+ /* Now that we've changed the variable search order to ignore the temp
+ environment, see if we need to change the cached IFS values. */
+ sv_ifs ("IFS");
tlist2 = expand_words_no_vars (tlist1);
expanding_redir = 0;
+ /* Now we need to change the variable search order back to include the temp
+ environment. We force the temp environment search by forcing
+ executing_builtin to 1. This is what makes `read' get the right values
+ for the IFS-related cached variables, for example. */
+ old = executing_builtin;
+ executing_builtin = 1;
+ sv_ifs ("IFS");
+ executing_builtin = old;
dispose_words (tlist1);
if (!tlist2 || tlist2->next)
WORD_DESC *redirectee;
{
char *herestr;
- int herelen, n, e;
+ int herelen, n, e, old;
expanding_redir = 1;
+ /* Now that we've changed the variable search order to ignore the temp
+ environment, see if we need to change the cached IFS values. */
+ sv_ifs ("IFS");
herestr = expand_string_to_string (redirectee->word, 0);
expanding_redir = 0;
+ /* Now we need to change the variable search order back to include the temp
+ environment. We force the temp environment search by forcing
+ executing_builtin to 1. This is what makes `read' get the right values
+ for the IFS-related cached variables, for example. */
+ old = executing_builtin;
+ executing_builtin = 1;
+ sv_ifs ("IFS");
+ executing_builtin = old;
+
herelen = STRLEN (herestr);
n = write (fd, herestr, herelen);
WORD_DESC *redirectee;
{
char *document;
- int document_len, fd2;
+ int document_len, fd2, old;
FILE *fp;
register WORD_LIST *t, *tlist;
}
expanding_redir = 1;
+ /* Now that we've changed the variable search order to ignore the temp
+ environment, see if we need to change the cached IFS values. */
+ sv_ifs ("IFS");
tlist = expand_string (redirectee->word, Q_HERE_DOCUMENT);
expanding_redir = 0;
+ /* Now we need to change the variable search order back to include the temp
+ environment. We force the temp environment search by forcing
+ executing_builtin to 1. This is what makes `read' get the right values
+ for the IFS-related cached variables, for example. */
+ old = executing_builtin;
+ executing_builtin = 1;
+ sv_ifs ("IFS");
+ executing_builtin = old;
if (tlist)
{
v = convert_var_to_assoc (v);
else if (v == 0)
v = make_new_array_variable (name);
- else if (v && array_p (v) == 0)
+ else if (v && mkassoc == 0 && array_p (v) == 0)
v = convert_var_to_array (v);
assign_compound_array_list (v, list, flags);
}
else
{
temp = string_list_dollar_at (list, quoted);
- if (ifs_is_set == 0 || ifs_is_null)
-{
-itrace("param_expand: set W_SPLITSPACE flag");
+ if (quoted == 0 && (ifs_is_set == 0 || ifs_is_null))
tflag |= W_SPLITSPACE;
-}
}
if (expand_no_split_dollar_star == 0 && contains_dollar_at)
&temp_has_dollar_at, "ed_dollar_at,
&had_quoted_null, pflags);
has_dollar_at += temp_has_dollar_at;
-
split_on_spaces += (tword->flags & W_SPLITSPACE);
-if (tword->flags & W_SPLITSPACE)
- itrace("expand_word_internal: param_expand return word has W_SPLITSPACE");
if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
{
{
char *ifs_chars;
-itrace("expand_word_internal: splitting `%s': split_on_spaces = %d", istring, split_on_spaces);
ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
/* If we have $@, we need to split the results no matter what. If
positional parameters with a space, so we split on space (we have
set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
string_list_dollar_at has separated the positional parameters
- with the first character of $IFS, so we split on $IFS. */
- if (has_dollar_at && ifs_chars)
+ with the first character of $IFS, so we split on $IFS. If
+ SPLIT_ON_SPACES is set, we expanded $* (unquoted) with IFS either
+ unset or null, and we want to make sure that we split on spaces
+ regardless of what else has happened to IFS since the expansion. */
+ if (split_on_spaces)
+ list = list_string (istring, " ", 1); /* XXX quoted == 1? */
+ else if (has_dollar_at && ifs_chars)
list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
else
{
make_internal_declare (tlist->word->word, "-gA");
else if (tlist->word->flags & W_ASSIGNASSOC)
make_internal_declare (tlist->word->word, "-A");
- if ((tlist->word->flags & (W_ASSIGNARRAY|W_ASSNGLOBAL)) == (W_ASSIGNARRAY|W_ASSNGLOBAL))
+ else if ((tlist->word->flags & (W_ASSIGNARRAY|W_ASSNGLOBAL)) == (W_ASSIGNARRAY|W_ASSNGLOBAL))
make_internal_declare (tlist->word->word, "-ga");
else if (tlist->word->flags & W_ASSIGNARRAY)
make_internal_declare (tlist->word->word, "-a");
# tests for expansions of $* when $1 == ""; problem through bash-4.2
${THIS_SH} ./dollar-star6.sub
+# tests for expansions of $* (unquoted) when IFS changes (e.g., ${IFS:=-})
+# problem through bash-4.2
+${THIS_SH} ./dollar-star7.sub
+
exit 0
--- /dev/null
+# if IFS side effects in ${IFS=} assignments take place, how do you cope with
+# later changes to IFS in the same set of expansions? You've already
+# committed to using the first character of the (old) IFS to expand $* in
+# the previous expansions, and changing it to not include ' ', for instance,
+# results in the first couple of ${*} below not being split at all
+
+set -f -- a b c
+
+unset -v IFS
+printf '<%s> ' ${*}${IFS=}${*}${IFS:=-}"${*}"
+echo
+printf "after 1: IFS "
+echo "${IFS-unset}"
+recho "$*"
+
+set -f -- a 'b c' d
+unset -v IFS
+printf '<%s> ' ${*}${IFS=}${*}${IFS:=-}"${*}"
+echo
+printf "after 2: IFS "
+echo "${IFS-unset}"
+recho "$*"
+
+unset -v IFS
+recho $*
+recho "$*"
+
+IFS=' '
+recho $*
+recho "$*"
argv[1] = <AwR>
argv[1] = <AwR>
argv[1] = <A^?R>
+<a> <b> <ca> <b> <c-a-b-c>
+after 1: IFS -
+argv[1] = <a-b-c>
+<a> <b> <c> <da> <b c> <d-a-b c-d>
+after 2: IFS -
+argv[1] = <a-b c-d>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[1] = <a b c d>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[1] = <a b c d>
argv[1] = <c>
argv[1] = <c>
argv[1] = <c>
+argv[1] = <correct>
+argv[2] = <>
+argv[1] = <correct>
+argv[2] = <>
+argv[1] = <correct>
+argv[2] = <>
+argv[1] = <XwrongX>
+argv[2] = <>
+argv[1] = <correct>
+argv[2] = <a>
+argv[1] = <XwrongX>
+argv[2] = <a>
+argv[1] = <correct>
+argv[2] = <a>
+argv[1] = <correct>
+argv[2] = <a>
recho """"""""c
recho c""""""""
+
+# BASH BUG: spurious DEL characters appear on empty variable interpolation.
+# BASH 4.2.8(1)-release
+
+a=''
+
+recho correct "$a" # correct empty output line
+recho correct "$a""$a" # correct empty output line
+recho correct "$a""$a""$a" # correct empty output line
+recho XwrongX "$a""$a""$a""$a" # spurious two DEL chars appear at line end
+recho correct a"$a" # correct single "a" on line
+recho XwrongX a"$a""$a" # spurious DEL char appears at line end
+recho correct a"$a$a" # correct single "a" on line
+recho correct a"$a$a$a$a" # correct single "a" on line
trap: 8
+[9] echo 4
4
+exit subshell 1
+current shell
+exit subshell 2
+current shell
+current shell
+current shell
+outside 1
+outside 2
+outside 3
+outside 4
caught a child death
caught a child death
caught a child death
${THIS_SH} ./trap3.sub
+${THIS_SH} ./trap4.sub
+
#
# show that setting a trap on SIGCHLD is not disastrous.
#
--- /dev/null
+# make sure subshells at the end of pipelines run any exit traps they set
+
+: | { trap 'echo exit subshell 1' EXIT; exit; }; echo current shell
+
+: | { trap 'echo exit subshell 2' EXIT; exit; }; echo current shell
+
+: | { trap 'echo exit subshell 3' EXIT; exit; } | : ; echo current shell
+
+: | { trap 'echo exit subshell 4' EXIT; exit; } | : ; echo current shell
+
+trap 'echo inherited exit trap' EXIT
+: | { exit; } ; echo outside 1
+: | ( exit; ) ; echo outside 2
+: | { exit; } | : ; echo outside 3
+: | ( exit; ) | : ; echo outside 4
+
+trap - EXIT
g: v = , w =
f: v = , w =
FIN: v = two, w = one
+declare -Ar FOOBAR='([foo]="bar" )'
+declare -Ar FOOBAR='([foo]="bar" )'
+declare -ar FOOBAR2='([0]="bar")'
+declare -ar FOOBAR2='([0]="bar")'
a=z
a=b
a=z
# scoping problems with declare -g through bash-4.2
${THIS_SH} ./varenv4.sub
+# more scoping and declaration problems with -g and arrays through bash-4.2
+${THIS_SH} ./varenv5.sub
+
# make sure variable scoping is done right
tt() { typeset a=b;echo a=$a; };a=z;echo a=$a;tt;echo a=$a
--- /dev/null
+function foobar {
+ declare -rgA FOOBAR=([foo]=bar)
+ declare -p FOOBAR
+}
+foobar
+declare -p FOOBAR
+
+unset -f foobar
+
+foobar() {
+ declare -rga FOOBAR2=([foo]=bar)
+ declare -p FOOBAR2
+}
+
+foobar
+declare -p FOOBAR2
return -1;
}
+/* Convenience functions the rest of the shell can use */
void
check_signals_and_traps ()
{
run_pending_traps ();
}
+void
+check_signals ()
+{
+ QUIT;
+}
+
#if defined (JOB_CONTROL) && defined (SIGCHLD)
#ifdef INCLUDE_UNUSED
#include "builtins/getopt.h"
#include "builtins/common.h"
+#include "builtins/builtext.h"
#if defined (READLINE)
# include "bashline.h"
{
SHELL_VAR *var;
int search_tempenv;
+ VAR_CONTEXT *vc;
var = (SHELL_VAR *)NULL;
if (search_tempenv && temporary_env)
var = hash_lookup (name, temporary_env);
+ vc = shell_variables;
+#if 0
+if (search_tempenv == 0 && /* (subshell_environment & SUBSHELL_COMSUB) && */
+ expanding_redir &&
+ (this_shell_builtin == eval_builtin || this_shell_builtin == command_builtin))
+ {
+ itrace("find_variable_internal: search_tempenv == 0: skipping VC_BLTNENV");
+ while (vc && (vc->flags & VC_BLTNENV))
+ vc = vc->down;
+ if (vc == 0)
+ vc = shell_variables;
+ }
+#endif
+
if (var == 0)
- var = var_lookup (name, shell_variables);
+ var = var_lookup (name, vc);
if (var == 0)
return ((SHELL_VAR *)NULL);
array_needs_making = 1;
-#if 0
- if (ifsname (name))
- setifs (var);
-else
-#endif
if (flags)
stupidly_hack_special_variables (name);
#include "builtins/getopt.h"
#include "builtins/common.h"
+#include "builtins/builtext.h"
#if defined (READLINE)
# include "bashline.h"
{
SHELL_VAR *var;
int search_tempenv;
+ VAR_CONTEXT *vc;
var = (SHELL_VAR *)NULL;
if (search_tempenv && temporary_env)
var = hash_lookup (name, temporary_env);
+ vc = shell_variables;
+#if 0
+if (search_tempenv == 0 && /* (subshell_environment & SUBSHELL_COMSUB) && */
+ expanding_redir &&
+ (this_shell_builtin == eval_builtin || this_shell_builtin == command_builtin))
+ {
+ itrace("find_variable_internal: search_tempenv == 0: skipping VC_BLTNENV");
+ while (vc && (vc->flags & VC_BLTNENV))
+ vc = vc->down;
+ if (vc == 0)
+ vc = shell_variables;
+ }
+#endif
+
if (var == 0)
- var = var_lookup (name, shell_variables);
+ var = var_lookup (name, vc);
if (var == 0)
return ((SHELL_VAR *)NULL);
update_export_env_inplace ("_=", 2, command_name);
}
-#if 0 /* UNUSED -- it caused too many problems */
-void
-put_gnu_argv_flags_into_env (pid, flags_string)
- intmax_t pid;
- char *flags_string;
-{
- char *dummy, *pbuf;
- int l, fl;
-
- pbuf = itos (pid);
- l = strlen (pbuf);
-
- fl = strlen (flags_string);
-
- dummy = (char *)xmalloc (l + fl + 30);
- dummy[0] = '_';
- strcpy (dummy + 1, pbuf);
- strcpy (dummy + 1 + l, "_GNU_nonoption_argv_flags_");
- dummy[l + 27] = '=';
- strcpy (dummy + l + 28, flags_string);
-
- free (pbuf);
-
- export_env = add_or_supercede_exported_var (dummy, 0);
-}
-#endif
-
/* **************************************************************** */
/* */
/* Managing variable contexts */