commit bash-20160429 snapshot

This commit is contained in:
Chet Ramey
2016-05-06 08:54:48 -04:00
parent 179593da61
commit f30e223041
24 changed files with 292 additions and 56 deletions
+84
View File
@@ -10714,3 +10714,87 @@ lib/readline/complete.c
or equal to the length of the string to be printed (print_len), make
sure to set the prefix length to 0 so the entire string is printed.
From a report from Grisha Levit <grishalevit@gmail.com>
4/25
----
subst.c
- command_substitute: update the conditions under which we give the
terminal to pipeline_pgrp with give_terminal_to to the same ones
where wait_for uses to decide whether to give the terminal back to
shell_pgrp. This code exists to undo the work wait_for does; it
has to give the terminal back to pipeline_pgrp only under those
conditions when wait_for gives it back to the shell pgrp. Fix for
bug reported by Paulo Bardes <bardes0022@gmail.com>
4/26
----
bashline.c
- bash_filename_stat_hook: temporarily disable the `nounset' shell
option around calls to expand_prompt_string so we don't get error
messages during completion. Fixes issue reported by Eric Pruitt
<eric.pruitt@gmail.com>
4/27
----
doc/{bash.1,bashref.texi}
- extdebug: clarify that having this option enabled at shell startup
acts identically to --debugger. From a report from Grisha Levit
<grishalevit@gmail.com>
jobs.[ch]
- wait_for_single_pid: now takes additional `int flags' argument
{jobs,execute_cmd}.c,builtins/wait.def
- wait_for_single_pid: changed callers to add extra argument
jobs.c
- wait_for_single_pid: if (flags & 1) == 0, don't print the error message
if PID isn't found; changed execute_pipeline call when lastpipe is
set
4/28
----
general.c
- bash_tilde_expand: try not setting interrupt_immediately or
terminate_immediately; see what happens with networked password
databases
4/29
----
subst.c
- parameter_brace_expand, parameter_brace_expand_rhs: now take an
additional `pflags' argument from its caller so we can pass
state
- parameter_brace_expand_rhs: if expand_string_for_rhs returns a
quoted null, but l_hasdollat is set to 1, meaning we saw a quoted
"$@" of some form, we need to turn off special handling of "$@"
so something like "${@-${@-$@}}" expands to an empty string like
Posix says it should. Fixes bug reported by Grisha Levit
<grishalevit@gmail.com>
5/1
---
variables.c
- bind_variable_internal: if we have a nameref variable with a valid
array reference that is invalid for assignment (e.g., a[*]), and
assign_array_element returns NULL, short-circuit and return NULL.
Fixes bug reported by Grisha Levit <grishalevit@gmail.com>
general.[ch]
- valid_nameref_value: new function, return 1 if passed argument is
a valid variable name argument for a nameref variable: a valid
identifier, a valid array reference, or a valid positional
parameter. Second argument indicates whether the value is to be
used for an assignment; in this case, return an error if the name
consists of all digits
builtins/declare.def
- declare_internal: disallow values for nameref variables that don't
pass the tests in valid_nameref_value. Part of fix for bug
reported by Grisha Levit <grishalevit@gmail.com>
variables.c
- bind_variable_internal: if trying to assign a value to a nameref
variable, throw an error if valid_nameref_value fails (with a second
argument of 1). More fixes for bug reported by Grisha Levit
<grishalevit@gmail.com>
+1
View File
@@ -1061,6 +1061,7 @@ tests/jobs.right f
tests/lastpipe.right f
tests/lastpipe.tests f
tests/lastpipe1.sub f
tests/lastpipe2.sub f
tests/mapfile.data f
tests/mapfile.right f
tests/mapfile.tests f
+12
View File
@@ -54,6 +54,7 @@
#include "pathexp.h"
#include "shmbutil.h"
#include "trap.h"
#include "flags.h"
#if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
# include <mbstr.h> /* mbschr */
@@ -1648,6 +1649,11 @@ bash_default_completion (text, start, end, qc, compflags)
else
{
matches = rl_completion_matches (text, variable_completion_function);
/* If a single match, see if it expands to a directory name and append
a slash if it does. This requires us to expand the variable name,
so we don't want to display errors if the variable is unset. This
can happen with dynamic variables whose value has never been
requested. */
if (matches && matches[0] && matches[1] == 0)
{
t = savestring (matches[0]);
@@ -3124,6 +3130,7 @@ bash_filename_stat_hook (dirname)
{
char *local_dirname, *new_dirname, *t;
int should_expand_dirname, return_value;
int global_nounset;
WORD_LIST *wl;
struct stat sb;
@@ -3140,7 +3147,12 @@ bash_filename_stat_hook (dirname)
if (should_expand_dirname)
{
new_dirname = savestring (local_dirname);
/* no error messages, and expand_prompt_string doesn't longjmp so we don't
have to worry about restoring this setting. */
global_nounset = unbound_vars_is_error;
unbound_vars_is_error = 0;
wl = expand_prompt_string (new_dirname, 0, W_NOCOMSUB); /* does the right thing */
unbound_vars_is_error = global_nounset;
if (wl)
{
free (new_dirname);
+10 -4
View File
@@ -341,8 +341,8 @@ declare_internal (list, local_var)
assign_error++;
NEXT_VARIABLE ();
}
#if 0
if (value && *value && legal_identifier (value) == 0)
#if 1
if (value && *value && valid_nameref_value (value, 0) == 0)
{
builtin_error (_("%s: invalid variable name for name reference"), value);
assign_error++;
@@ -402,6 +402,12 @@ declare_internal (list, local_var)
var = make_local_array_variable (name, making_array_special);
else
#endif
if (offset == 0 && (flags_on & att_nameref))
{
refvar = mkglobal ? find_global_variable_last_nameref (name) : find_variable_last_nameref (name);
var = 0;
}
else
var = make_local_variable (name); /* sets att_invisible for new vars */
if (var == 0)
{
@@ -570,8 +576,8 @@ declare_internal (list, local_var)
}
else if (flags_on & att_nameref)
{
#if 0
if (nameref_p (var) == 0 && var_isset (var) && var_isnull (var) == 0 && legal_identifier (value_cell (var)) == 0)
#if 1
if (nameref_p (var) == 0 && var_isset (var) && var_isnull (var) == 0 && valid_nameref_value (value_cell (var), 0) == 0)
{
builtin_error (_("%s: invalid variable name for name reference"), value_cell (var));
any_failed++;
+1 -1
View File
@@ -179,7 +179,7 @@ wait_builtin (list)
if (legal_number (w, &pid_value) && pid_value == (pid_t)pid_value)
{
pid = (pid_t)pid_value;
status = wait_for_single_pid (pid);
status = wait_for_single_pid (pid, 1);
}
else
{
+5 -3
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
.\" Last Change: Mon Feb 8 10:15:48 EST 2016
.\" Last Change: Wed Apr 27 09:19:58 EDT 2016
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2016 February 8" "GNU Bash 4.4"
.TH BASH 1 "2016 April 27" "GNU Bash 4.4"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -9627,7 +9627,9 @@ If set, aliases are expanded as described above under
This option is enabled by default for interactive shells.
.TP 8
.B extdebug
If set, behavior intended for use by debuggers is enabled:
If set at shell invocation, arrange to execute the debugger profile
before the shell starts, identical to the \fB\-\-debugger\fP option.
If set after invocation, behavior intended for use by debuggers is enabled:
.RS
.TP
.B 1.
+4 -2
View File
@@ -1513,7 +1513,7 @@ When applied to a string-valued variable, @var{value} is expanded and
appended to the variable's value.
A variable can be assigned the @var{nameref} attribute using the
@option{-n} option to the \fBdeclare\fP or \fBlocal\fP builtin commands
@option{-n} option to the @code{declare} or @code{local} builtin commands
(@pxref{Bash Builtins})
to create a @var{nameref}, or a reference to another variable.
This allows variables to be manipulated indirectly.
@@ -5143,7 +5143,9 @@ If set, aliases are expanded as described below under Aliases,
This option is enabled by default for interactive shells.
@item extdebug
If set, behavior intended for use by debuggers is enabled:
If set at shell invocation, arrange to execute the debugger profile
before the shell starts, identical to the @option{--debugger} option.
If set after invocation, behavior intended for use by debuggers is enabled:
@enumerate
@item
+3 -3
View File
@@ -2,10 +2,10 @@
Copyright (C) 1988-2016 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Sun Feb 28 15:32:09 EST 2016
@set LASTCHANGE Wed Apr 27 09:19:38 EDT 2016
@set EDITION 4.4
@set VERSION 4.4
@set UPDATED 28 February 2016
@set UPDATED-MONTH February 2016
@set UPDATED 27 April 2016
@set UPDATED-MONTH April 2016
+1 -1
View File
@@ -2486,7 +2486,7 @@ execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close)
lstdin = wait_for (lastpid);
}
else
lstdin = wait_for_single_pid (lastpid); /* checks bgpids list */
lstdin = wait_for_single_pid (lastpid, 0); /* checks bgpids list */
#else
lstdin = wait_for (lastpid);
#endif
+23 -1
View File
@@ -1,6 +1,6 @@
/* general.c -- Stuff that is used by all files. */
/* Copyright (C) 1987-2015 Free Software Foundation, Inc.
/* Copyright (C) 1987-2016 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -227,6 +227,24 @@ legal_identifier (name)
return (1);
}
int
valid_nameref_value (name, for_assignment)
char *name;
int for_assignment;
{
intmax_t r;
#if defined (ARRAY_VARS)
if (legal_identifier (name) || valid_array_reference (name, 0))
#else
if (legal_identifier (name))
#endif
return 1;
if (for_assignment == 0 && legal_number (name, &r))
return 1;
return 0;
}
/* Make sure that WORD is a valid shell identifier, i.e.
does not contain a dollar sign, nor is quoted in any way. Nor
does it consist of all digits. If CHECK_WORD is non-zero,
@@ -1039,6 +1057,7 @@ bash_tilde_expand (s, assign_p)
int old_immed, old_term, r;
char *ret;
#if 0
old_immed = interrupt_immediately;
old_term = terminate_immediately;
/* We want to be able to interrupt tilde expansion. Ordinarily, we can just
@@ -1048,6 +1067,7 @@ bash_tilde_expand (s, assign_p)
if (any_signals_trapped () < 0)
interrupt_immediately = 1;
terminate_immediately = 1;
#endif
tilde_additional_prefixes = assign_p == 0 ? (char **)0
: (assign_p == 2 ? bash_tilde_prefixes2 : bash_tilde_prefixes);
@@ -1057,8 +1077,10 @@ bash_tilde_expand (s, assign_p)
r = (*s == '~') ? unquoted_tilde_word (s) : 1;
ret = r ? tilde_expand (s) : savestring (s);
#if 0
interrupt_immediately = old_immed;
terminate_immediately = old_term;
#endif
QUIT;
+2 -1
View File
@@ -1,6 +1,6 @@
/* general.h -- defines that everybody likes to use. */
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
/* Copyright (C) 1993-2016 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -289,6 +289,7 @@ extern int legal_identifier __P((char *));
extern int importable_function_name __P((char *, size_t));
extern int exportable_function_name __P((char *));
extern int check_identifier __P((WORD_DESC *, int));
extern int valid_nameref_value __P((char *, int));
extern int legal_alias_name __P((char *, int));
extern int assignment __P((const char *, int));
+13 -5
View File
@@ -2313,10 +2313,13 @@ find_last_pid (job, block)
This low-level function prints an error message if PID is not
a child of this shell. It returns -1 if it fails, or whatever
wait_for returns otherwise. If the child is not found in the
jobs table, it returns 127. */
jobs table, it returns 127. If FLAGS doesn't include 1, we
suppress the error message if PID isn't found. */
int
wait_for_single_pid (pid)
wait_for_single_pid (pid, flags)
pid_t pid;
int flags;
{
register PROCESS *child;
sigset_t set, oset;
@@ -2335,7 +2338,8 @@ wait_for_single_pid (pid)
if (child == 0)
{
internal_error (_("wait: pid %ld is not a child of this shell"), (long)pid);
if (flags & 1)
internal_error (_("wait: pid %ld is not a child of this shell"), (long)pid);
return (127);
}
@@ -2395,7 +2399,7 @@ wait_for_background_pids ()
UNBLOCK_CHILD (oset);
QUIT;
errno = 0; /* XXX */
r = wait_for_single_pid (pid);
r = wait_for_single_pid (pid, 1);
if (r == -1)
{
/* If we're mistaken about job state, compensate. */
@@ -2789,7 +2793,11 @@ itrace("wait_for: blocking wait for %d returns %d child = %p", (int)pid, r, chil
if (job == NO_JOB)
itrace("wait_for: job == NO_JOB, giving the terminal to shell_pgrp (%ld)", (long)shell_pgrp);
#endif
/* Don't modify terminal pgrp if we are running in background or a subshell */
/* Don't modify terminal pgrp if we are running in background or a
subshell. Make sure subst.c:command_substitute uses the same
conditions to determine whether or not it should undo this and
give the terminal to pipeline_pgrp. */
if (running_in_background == 0 && (subshell_environment&(SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0)
give_terminal_to (shell_pgrp, 0);
}
+1 -1
View File
@@ -230,7 +230,7 @@ extern int set_tty_state __P((void));
extern int job_exit_status __P((int));
extern int job_exit_signal __P((int));
extern int wait_for_single_pid __P((pid_t));
extern int wait_for_single_pid __P((pid_t, int));
extern void wait_for_background_pids __P((void));
extern int wait_for __P((pid_t));
extern int wait_for_job __P((int));
+29 -1
View File
@@ -1435,12 +1435,16 @@ It understands the EOF character or "exit" to exit the program.
@example
/* Standard include files. stdio.h is required. */
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <locale.h>
/* Used for select(2) */
#include <sys/types.h>
#include <sys/select.h>
#include <signal.h>
#include <stdio.h>
/* Standard readline include files. */
@@ -1448,10 +1452,20 @@ It understands the EOF character or "exit" to exit the program.
#include <readline/history.h>
static void cb_linehandler (char *);
static void sighandler (int);
int running;
int sigwinch_received;
const char *prompt = "rltest$ ";
/* Handle SIGWINCH and window size changes when readline is not active and
reading a character. */
static void
sighandler (int sig)
@{
sigwinch_received = 1;
@}
/* Callback function called for each line when accept-line executed, EOF
seen, or EOF character read. This sets a flag and returns; it could
also call exit(3). */
@@ -1486,6 +1500,13 @@ main (int c, char **v)
fd_set fds;
int r;
/* Set the default locale values according to environment variables. */
setlocale (LC_ALL, "");
/* Handle window size changes when readline is not active and reading
characters. */
signal (SIGWINCH, sighandler);
/* Install the line handler. */
rl_callback_handler_install (prompt, cb_linehandler);
@@ -1500,12 +1521,19 @@ main (int c, char **v)
FD_SET (fileno (rl_instream), &fds);
r = select (FD_SETSIZE, &fds, NULL, NULL, NULL);
if (r < 0)
if (r < 0 && errno != EINTR)
@{
perror ("rltest: select");
rl_callback_handler_remove ();
break;
@}
if (sigwinch_received)
@{
rl_resize_terminal ();
sigwinch_received = 0;
}@
if (r < 0)
continue;
if (FD_ISSET (fileno (rl_instream), &fds))
rl_callback_read_char ();
+5 -1
View File
@@ -236,7 +236,11 @@ tilde_expand (string)
string += end;
expansion = tilde_expand_word (tilde_word);
xfree (tilde_word);
if (expansion == 0)
expansion = tilde_word;
else
xfree (tilde_word);
len = strlen (expansion);
#ifdef __CYGWIN__
+46 -27
View File
@@ -4,7 +4,7 @@
/* ``Have a little faith, there's magic in the night. You ain't a
beauty, but, hey, you're alright.'' */
/* Copyright (C) 1987-2015 Free Software Foundation, Inc.
/* Copyright (C) 1987-2016 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -170,9 +170,9 @@ int no_longjmp_on_fatal_error = 0;
/* Extern functions and variables from different files. */
extern int last_command_exit_value, last_command_exit_signal;
extern int subshell_environment, line_number;
extern int subshell_environment, running_in_background;
extern int subshell_level, parse_and_execute_level, sourcelevel;
extern int eof_encountered;
extern int eof_encountered, line_number;
extern int return_catch_flag, return_catch_value;
extern pid_t dollar_dollar_pid;
extern int posixly_correct;
@@ -310,7 +310,7 @@ static int chk_arithsub __P((const char *, int));
static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int, arrayind_t *));
static char *parameter_brace_find_indir __P((char *, int, int, int));
static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int, int *, int *));
static void parameter_brace_expand_error __P((char *, char *));
static int valid_length_expression __P((char *));
@@ -3728,9 +3728,9 @@ expand_string_leave_quoted (string, quoted)
/* This does not perform word splitting or dequote the WORD_LIST
it returns. */
static WORD_LIST *
expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
expand_string_for_rhs (string, quoted, dollar_at_p, expanded_p)
char *string;
int quoted, *dollar_at_p, *has_dollar_at;
int quoted, *dollar_at_p, *expanded_p;
{
WORD_DESC td;
WORD_LIST *tresult;
@@ -3741,7 +3741,7 @@ expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
expand_no_split_dollar_star = 1;
td.flags = W_NOSPLIT2; /* no splitting, remove "" and '' */
td.word = string;
tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, expanded_p);
expand_no_split_dollar_star = 0;
return (tresult);
@@ -6174,8 +6174,13 @@ command_substitute (string, quoted)
pipeline_pgrp is non-zero only while we are constructing a
pipeline, so what we are concerned about is whether or not that
pipeline was started in the background. A pipeline started in
the background should never get the tty back here. */
if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
the background should never get the tty back here. We duplicate
the conditions that wait_for tests to make sure we only give
the terminal back to pipeline_pgrp under the conditions that wait_for
gave it to shell_pgrp. If wait_for doesn't mess with the terminal
pgrp, we should not either. */
if (interactive && pipeline_pgrp != (pid_t)0 && running_in_background == 0 &&
(subshell_environment & (SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0)
give_terminal_to (pipeline_pgrp, 0);
#endif /* JOB_CONTROL */
@@ -6579,45 +6584,49 @@ parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, c
"-", "+", or "=". QUOTED is true if the entire brace expression occurs
between double quotes. */
static WORD_DESC *
parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
parameter_brace_expand_rhs (name, value, c, quoted, pflags, qdollaratp, hasdollarat)
char *name, *value;
int c, quoted, *qdollaratp, *hasdollarat;
int c, quoted, pflags, *qdollaratp, *hasdollarat;
{
WORD_DESC *w;
WORD_LIST *l;
char *t, *t1, *temp, *vname;
int hasdol;
int l_hasdollat, sindex;
/*itrace("parameter_brace_expand_rhs: %s:%s pflags = %d", name, value, pflags);*/
/* If the entire expression is between double quotes, we want to treat
the value as a double-quoted string, with the exception that we strip
embedded unescaped double quotes (for sh backwards compatibility). */
if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value)
{
hasdol = 0;
temp = string_extract_double_quoted (value, &hasdol, 1);
sindex = 0;
temp = string_extract_double_quoted (value, &sindex, 1);
}
else
temp = value;
w = alloc_word_desc ();
hasdol = 0;
l_hasdollat = 0;
/* XXX was 0 not quoted */
l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
l = *temp ? expand_string_for_rhs (temp, quoted, &l_hasdollat, (int *)NULL)
: (WORD_LIST *)0;
if (hasdollarat)
*hasdollarat = hasdol || (l && l->next);
*hasdollarat = l_hasdollat || (l && l->next);
if (temp != value)
free (temp);
if (l)
{
/* If l->next is not null, we know that TEMP contained "$@", since that
is the only expansion that creates more than one word. */
if (qdollaratp && ((hasdol && quoted) || l->next))
*qdollaratp = 1;
if (qdollaratp && ((l_hasdollat && quoted) || l->next))
{
/*itrace("parameter_brace_expand_rhs: %s:%s: l != NULL, set *qdollaratp", name, value);*/
*qdollaratp = 1;
}
/* The expansion of TEMP returned something. We need to treat things
slightly differently if HASDOL is non-zero. If we have "$@", the
individual words have already been quoted. We need to turn them
slightly differently if L_HASDOLLAT is non-zero. If we have "$@",
the individual words have already been quoted. We need to turn them
into a string with the words separated by the first character of
$IFS without any additional quoting, so string_list_dollar_at won't
do the right thing. If IFS is null, we want "$@" to split into
@@ -6630,7 +6639,7 @@ parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
w->flags |= W_SPLITSPACE;
}
else
temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l);
temp = (l_hasdollat || l->next) ? string_list_dollar_star (l) : string_list (l);
/* If we have a quoted null result (QUOTED_NULL(temp)) and the word is
a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the
@@ -6641,24 +6650,32 @@ parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
if (l->next == 0 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL (temp) && QUOTED_NULL (l->word->word) && (l->word->flags & W_HASQUOTEDNULL))
{
w->flags |= W_HASQUOTEDNULL;
/*itrace("parameter_brace_expand_rhs (%s:%s): returning quoted null, turning off qdollaratp", name, value);*/
/* If we return a quoted null with L_HASDOLLARAT, we either have a
construct like "${@-$@}" or "${@-${@-$@}}" with no positional
parameters or a quoted expansion of "$@" with $1 == ''. In either
case, we don't want to enable special handling of $@. */
if (qdollaratp && l_hasdollat)
*qdollaratp = 0;
}
dispose_words (l);
}
else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && l_hasdollat)
{
/* Posix interp 221 changed the rules on this. The idea is that
something like "$xxx$@" should expand the same as "${foo-$xxx$@}"
when foo and xxx are unset. The problem is that it's not in any
way backwards compatible and few other shells do it. We're eventually
going to try and split the difference (heh) a little bit here. */
/* hasdol == 1 means we saw a quoted dollar at. */
/* l_hasdollat == 1 means we saw a quoted dollar at. */
/* The brace expansion occurred between double quotes and there was
a $@ in TEMP. It does not matter if the $@ is quoted, as long as
it does not expand to anything. In this case, we want to return
a quoted empty string. */
a quoted empty string. Posix interp 888 */
temp = make_quoted_char ('\0');
w->flags |= W_HASQUOTEDNULL;
/*itrace("parameter_brace_expand_rhs (%s:%s): returning quoted null", name, value);*/
}
else
temp = (char *)NULL;
@@ -7795,7 +7812,7 @@ chk_arithsub (s, len)
static WORD_DESC *
parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, contains_dollar_at)
char *string;
int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at, pflags;
int *indexp, quoted, pflags, *quoted_dollar_atp, *contains_dollar_at;
{
int check_nullness, var_is_set, var_is_null, var_is_special;
int want_substring, want_indir, want_patsub, want_casemod;
@@ -8299,6 +8316,7 @@ bad_substitution:
quoted |= Q_DOLBRACE;
ret = parameter_brace_expand_rhs (name, value, c,
quoted,
pflags,
quoted_dollar_atp,
contains_dollar_at);
/* XXX - fix up later, esp. noting presence of
@@ -8346,7 +8364,7 @@ bad_substitution:
removed. */
if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
quoted |= Q_DOLBRACE;
ret = parameter_brace_expand_rhs (name, value, c, quoted,
ret = parameter_brace_expand_rhs (name, value, c, quoted, pflags,
quoted_dollar_atp,
contains_dollar_at);
/* XXX - fix up later, esp. noting presence of
@@ -8388,6 +8406,7 @@ param_expand (string, sindex, quoted, expanded_something,
WORD_DESC *tdesc, *ret;
int tflag;
/*itrace("param_expand: `%s' pflags = %d", string+*sindex, pflags);*/
zindex = *sindex;
c = string[++zindex];
+1 -1
View File
@@ -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 -1
View File
@@ -129,7 +129,8 @@ ok 2
ok 3
echo shopt a
shopt a
echo a b c d 2 > /dev/null
echo a b c d 2> /dev/null
a b c d
!
!
!
+2
View File
@@ -123,6 +123,8 @@ echo ${!var2}
# history_comment_char
echo ok 3 # !1200
# bash versions through bash-4.3 fail this; they make the digit preceding the
# > into a separate word, changing the meaning of the redirection
shopt a b c d 2>/dev/null
echo !shopt-1
+9
View File
@@ -8,3 +8,12 @@ last = c
1 -- 0 0 1
1 -- 0 1 0
lastpipe1.sub returns 14
A1
A2
B1
B2
HI
A1
A2
B1
B2
+3
View File
@@ -56,3 +56,6 @@ set +o pipefail
${THIS_SH} ./lastpipe1.sub
echo lastpipe1.sub returns $?
${THIS_SH} ./lastpipe2.sub
+20
View File
@@ -0,0 +1,20 @@
shopt -s lastpipe
echo -e 'A\nB' | while read letter; do
echo -e '1\n2' | while read digit; do
echo $letter$digit
done
done
myPipefunc()
{
cat | tee $TMPDIR/outfile
}
echo HI | myPipefunc
echo -e 'A\nB' | while read letter; do
echo -e '1\n2' | while read digit; do
echo $letter$digit | myPipefunc
done
done
rm -f $TMPDIR/outfile
+1
View File
@@ -0,0 +1 @@
B2
+14 -3
View File
@@ -2629,15 +2629,26 @@ bind_variable_internal (name, value, table, hflags, aflags)
/* The first clause handles `declare -n ref; ref=x;' */
if (entry && invisible_p (entry) && nameref_p (entry))
goto assign_value;
{
if (valid_nameref_value (value, 1) == 0)
{
sh_invalidid (value);
return ((SHELL_VAR *)NULL);
}
goto assign_value;
}
else if (entry && nameref_p (entry))
{
newval = nameref_cell (entry);
#if defined (ARRAY_VARS)
/* declare -n foo=x[2] */
if (valid_array_reference (newval, 0))
/* XXX - should it be aflags? */
entry = assign_array_element (newval, make_variable_value (entry, value, 0), aflags);
{
/* XXX - should it be aflags? */
entry = assign_array_element (newval, make_variable_value (entry, value, 0), aflags);
if (entry == 0)
return entry;
}
else
#endif
{