mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-27 07:43:07 +02:00
commit bash-20130125 snapshot
This commit is contained in:
@@ -4203,6 +4203,9 @@ execute_cmd.c
|
||||
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
|
||||
@@ -4379,3 +4382,71 @@ command.h
|
||||
{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>
|
||||
|
||||
+56
-3
@@ -4203,6 +4203,9 @@ execute_cmd.c
|
||||
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
|
||||
@@ -4372,9 +4375,59 @@ subst.c
|
||||
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
|
||||
|
||||
@@ -867,6 +867,7 @@ tests/dollar-star3.sub f
|
||||
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
|
||||
@@ -1156,6 +1157,7 @@ tests/trap1.sub f 755
|
||||
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
|
||||
@@ -1170,6 +1172,7 @@ tests/varenv1.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
|
||||
|
||||
@@ -114,6 +114,11 @@ _evalfile (filename, flags)
|
||||
|
||||
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);
|
||||
@@ -133,11 +138,13 @@ file_error_and_exit:
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -146,6 +153,7 @@ file_error_and_exit:
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
+12
-4
@@ -410,12 +410,20 @@ read_builtin (list)
|
||||
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;
|
||||
|
||||
remove_unwind_protect ();
|
||||
run_unwind_frame ("read_builtin");
|
||||
input_string[i] = '\0'; /* make sure it's terminated */
|
||||
if (i == 0)
|
||||
{
|
||||
t = (char *)xmalloc (1);
|
||||
t[0] = 0;
|
||||
}
|
||||
else
|
||||
t = savestring (input_string);
|
||||
|
||||
run_unwind_frame ("read_builtin");
|
||||
input_string = t;
|
||||
retval = 128+SIGALRM;
|
||||
goto assign_vars;
|
||||
}
|
||||
|
||||
@@ -608,6 +608,8 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||
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)
|
||||
|
||||
@@ -3176,6 +3176,7 @@ waitchld (wpid, block)
|
||||
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 */
|
||||
|
||||
@@ -3191,9 +3192,9 @@ waitchld (wpid, block)
|
||||
: 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;
|
||||
|
||||
@@ -4236,8 +4237,10 @@ mark_dead_jobs_as_notified (force)
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ zread (fd, buf, len)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ int expanding_redir;
|
||||
|
||||
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;
|
||||
|
||||
@@ -275,6 +276,7 @@ redirection_expand (word)
|
||||
char *result;
|
||||
WORD_LIST *tlist1, *tlist2;
|
||||
WORD_DESC *w;
|
||||
int old;
|
||||
|
||||
w = copy_word (word);
|
||||
if (posixly_correct)
|
||||
@@ -282,11 +284,22 @@ redirection_expand (word)
|
||||
|
||||
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. */
|
||||
@@ -305,11 +318,23 @@ write_here_string (fd, redirectee)
|
||||
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);
|
||||
@@ -338,7 +363,7 @@ write_here_document (fd, redirectee)
|
||||
WORD_DESC *redirectee;
|
||||
{
|
||||
char *document;
|
||||
int document_len, fd2;
|
||||
int document_len, fd2, old;
|
||||
FILE *fp;
|
||||
register WORD_LIST *t, *tlist;
|
||||
|
||||
@@ -362,8 +387,19 @@ write_here_document (fd, redirectee)
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -63,6 +63,7 @@ int expanding_redir;
|
||||
|
||||
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;
|
||||
|
||||
@@ -156,14 +157,12 @@ redirection_error (temp, error)
|
||||
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;
|
||||
}
|
||||
@@ -277,6 +276,7 @@ redirection_expand (word)
|
||||
char *result;
|
||||
WORD_LIST *tlist1, *tlist2;
|
||||
WORD_DESC *w;
|
||||
int old;
|
||||
|
||||
w = copy_word (word);
|
||||
if (posixly_correct)
|
||||
@@ -284,8 +284,19 @@ redirection_expand (word)
|
||||
|
||||
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)
|
||||
@@ -307,11 +318,23 @@ write_here_string (fd, redirectee)
|
||||
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);
|
||||
@@ -340,7 +363,7 @@ write_here_document (fd, redirectee)
|
||||
WORD_DESC *redirectee;
|
||||
{
|
||||
char *document;
|
||||
int document_len, fd2;
|
||||
int document_len, fd2, old;
|
||||
FILE *fp;
|
||||
register WORD_LIST *t, *tlist;
|
||||
|
||||
@@ -364,8 +387,19 @@ write_here_document (fd, redirectee)
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -2729,7 +2729,7 @@ do_compound_assignment (name, value, flags)
|
||||
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);
|
||||
}
|
||||
@@ -7630,11 +7630,8 @@ param_expand (string, sindex, quoted, expanded_something,
|
||||
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)
|
||||
@@ -8214,10 +8211,7 @@ add_string:
|
||||
&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)
|
||||
{
|
||||
@@ -8660,7 +8654,6 @@ finished_with_string:
|
||||
{
|
||||
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
|
||||
@@ -8668,8 +8661,13 @@ itrace("expand_word_internal: splitting `%s': split_on_spaces = %d", istring, sp
|
||||
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
|
||||
{
|
||||
@@ -9328,7 +9326,7 @@ shell_expand_word_list (tlist, eflags)
|
||||
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");
|
||||
|
||||
@@ -245,4 +245,8 @@ ${THIS_SH} ./dollar-at5.sub
|
||||
# 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
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# 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 "$*"
|
||||
@@ -237,3 +237,19 @@ argv[1] = <A^?R>
|
||||
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>
|
||||
|
||||
@@ -189,3 +189,19 @@ argv[1] = <c>
|
||||
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>
|
||||
|
||||
@@ -14,3 +14,17 @@ recho """"c""""""
|
||||
|
||||
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
|
||||
|
||||
@@ -75,6 +75,16 @@ command substitution
|
||||
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
|
||||
|
||||
@@ -68,6 +68,8 @@ trap '' USR2
|
||||
|
||||
${THIS_SH} ./trap3.sub
|
||||
|
||||
${THIS_SH} ./trap4.sub
|
||||
|
||||
#
|
||||
# show that setting a trap on SIGCHLD is not disastrous.
|
||||
#
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# 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
|
||||
@@ -60,6 +60,10 @@ FIN: asdf fdsa, asdf fdsa
|
||||
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
|
||||
|
||||
@@ -208,5 +208,8 @@ $THIS_SH ./varenv3.sub
|
||||
# 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
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
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
|
||||
@@ -456,6 +456,7 @@ any_signals_trapped ()
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Convenience functions the rest of the shell can use */
|
||||
void
|
||||
check_signals_and_traps ()
|
||||
{
|
||||
@@ -463,6 +464,12 @@ check_signals_and_traps ()
|
||||
run_pending_traps ();
|
||||
}
|
||||
|
||||
void
|
||||
check_signals ()
|
||||
{
|
||||
QUIT;
|
||||
}
|
||||
|
||||
#if defined (JOB_CONTROL) && defined (SIGCHLD)
|
||||
|
||||
#ifdef INCLUDE_UNUSED
|
||||
|
||||
+17
-6
@@ -61,6 +61,7 @@
|
||||
|
||||
#include "builtins/getopt.h"
|
||||
#include "builtins/common.h"
|
||||
#include "builtins/builtext.h"
|
||||
|
||||
#if defined (READLINE)
|
||||
# include "bashline.h"
|
||||
@@ -1788,6 +1789,7 @@ find_variable_internal (name, force_tempenv)
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
int search_tempenv;
|
||||
VAR_CONTEXT *vc;
|
||||
|
||||
var = (SHELL_VAR *)NULL;
|
||||
|
||||
@@ -1801,8 +1803,22 @@ find_variable_internal (name, force_tempenv)
|
||||
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);
|
||||
@@ -2868,11 +2884,6 @@ assign_in_env (word, flags)
|
||||
|
||||
array_needs_making = 1;
|
||||
|
||||
#if 0
|
||||
if (ifsname (name))
|
||||
setifs (var);
|
||||
else
|
||||
#endif
|
||||
if (flags)
|
||||
stupidly_hack_special_variables (name);
|
||||
|
||||
|
||||
+17
-28
@@ -61,6 +61,7 @@
|
||||
|
||||
#include "builtins/getopt.h"
|
||||
#include "builtins/common.h"
|
||||
#include "builtins/builtext.h"
|
||||
|
||||
#if defined (READLINE)
|
||||
# include "bashline.h"
|
||||
@@ -1788,6 +1789,7 @@ find_variable_internal (name, force_tempenv)
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
int search_tempenv;
|
||||
VAR_CONTEXT *vc;
|
||||
|
||||
var = (SHELL_VAR *)NULL;
|
||||
|
||||
@@ -1801,8 +1803,22 @@ find_variable_internal (name, force_tempenv)
|
||||
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);
|
||||
@@ -4108,33 +4124,6 @@ put_command_name_into_env (command_name)
|
||||
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 */
|
||||
|
||||
Reference in New Issue
Block a user