commit bash-20161108 snapshot

This commit is contained in:
Chet Ramey
2016-11-10 11:32:12 -05:00
parent ec1101c37e
commit 78a3f8a4ba
13 changed files with 219 additions and 88 deletions
+90 -1
View File
@@ -12008,7 +12008,7 @@ aclocal.m4
----- -----
variables.c variables.c
- get_bashpid: BASHPID is no longer readonly; assignments to it are - get_bashpid: BASHPID is no longer readonly; assignments to it are
just ignored. Suggested by Martijn Dekker <martijn@inlv.org> just ignored.
doc/{bash.1,bashref.texi} doc/{bash.1,bashref.texi}
- BASHPID: note that assignments are ignored and unsetting BASHPID - BASHPID: note that assignments are ignored and unsetting BASHPID
@@ -12199,3 +12199,92 @@ lib/glob/sm_loop.c
- GMATCH: allow trailing backslash in pattern to explicitly match a - GMATCH: allow trailing backslash in pattern to explicitly match a
backslash that is the last character in the string. Bug report from backslash that is the last character in the string. Bug report from
Stephane Chazelas <stephane.chazelas@gmail.com> Stephane Chazelas <stephane.chazelas@gmail.com>
11/5
----
builtins/common.c
- display_signal_list: if displaying a signal name corresponding to an
exit status > 128, don't display the SIG prefix at all. Old code
made displaying the SIG prefix dependent on JOB_CONTROL define.
Report and fix from Martijn Dekker <martijn@inlv.org>
execute_cmd.c
- execute_subshell_builtin_or_function: call without_job_control even
if JOB_CONTROL is not defined. Similar to fix from 9/23.
Report from Martijn Dekker <martijn@inlv.org>
execute_cmd.c
- execute_simple_command: free memory allocated and passed to
make_child in the child process if JOB_CONTROL is defined
- execute_command_internal: free memory allocated and passed to
make_child in the child process created to run a () subshell or a
compound command within a pipeline if JOB_CONTROL is defined
- execute_coproc: free memory allocated and passed to make_child in
the child process if JOB_CONTROL is defined
- execute_disk_command: free memory allocated and passed to
make_child in the child process if JOB_CONTROL is defined. This
series of fixes is the result of reports from
Eduardo A. Bustamante López <dualbus@gmail.com>
11/6
----
lib/sh/unicode.c
- u32toutf16: fix to prevent outputting broken surrogate pairs for
Japanese locales (ja_JP.UTF-8) on cygwin (which uses UTF-16 natively).
Report and fix from Koichi MURASE <myoga.murase@gmail.com>
builtins/trap.def
- trap_builtin: if OP is `-' (revert), set the SIGINT signal handler
to sigint_sighandler if the shell is interactive and sourcing a
file (interactive_shell && sourcelevel) or running a trap
(interactive_shell && running_trap) even if it's not currently
interactive. Report from Martijn Dekker <martijn@inlv.org>
builtins/read.def
- check for and read multibyte characters in all cases, not just when
we are reading a specific number of characters, as long as
mb_cur_max > 1
subst.c
- expand_word_internal: some improvements to code that converts istring
into a WORD_LIST * to avoid multiple allocations and copies of
istring, which is already malloc'ed memory -- reduce number of malloc
and free calls
test.c
- unary_test: make sure if we test -v array[@] or array[*] that we
free the return value from array_value
11/8
----
expr.c
- expcond: make sure to set `noeval' before reading tokens depending on
the result of the conditional test, since readtok() can evaluate
identifiers (and recursively those containing expressions). Report
and fix from Koichi MURASE <myoga.murase@gmail.com>
builtins/evalstring.c
- should_suppress_fork: make sure to check for traps on EXIT and
ERR, since any_signals_trapped() only checks for `real' signals,
not the fake shell ones. Fixes bug reported by Werner Fink
<werner@suse.de>
- optimize_subshell_command: ditto
11/9
----
eval.c
- reader_loop: change so that we don't reset the SIGINT handler every
time through the command loop in an interactive shell if the signal
is trapped (as the comment noted). Reported by Report from Martijn
Dekker <martijn@inlv.org>
subst.c
- parameter_brace_{patsub,remove_pattern,transform,casemod}: save and
restore this_command_name while temporarily setting it for use in
error messages. Fixes use-after-free error reported by
op7ic \x00 <op7ica@gmail.com>
- string_extract_verbatim: make sure when we increment i by 2 due to
a CTLESC or CTLESC-CTLNUL that we don't read past the end of the
string. This can happen if the string ends with an odd number of
CTLESC chars. Fixes oob-read error reported by
op7ic \x00 <op7ica@gmail.com>
-4
View File
@@ -782,13 +782,9 @@ display_signal_list (list, forcecols)
list = list->next; list = list->next;
continue; continue;
} }
#if defined (JOB_CONTROL)
/* POSIX.2 says that `kill -l signum' prints the signal name without /* POSIX.2 says that `kill -l signum' prints the signal name without
the `SIG' prefix. */ the `SIG' prefix. */
printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name); printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
#else
printf ("%s\n", name);
#endif
} }
else else
{ {
+2 -3
View File
@@ -104,12 +104,9 @@ should_suppress_fork (command)
running_trap == 0 && running_trap == 0 &&
*bash_input.location.string == '\0' && *bash_input.location.string == '\0' &&
command->type == cm_simple && command->type == cm_simple &&
#if 0
signal_is_trapped (EXIT_TRAP) == 0 && signal_is_trapped (EXIT_TRAP) == 0 &&
signal_is_trapped (ERROR_TRAP) == 0 && signal_is_trapped (ERROR_TRAP) == 0 &&
#else
any_signals_trapped () < 0 && any_signals_trapped () < 0 &&
#endif
command->redirects == 0 && command->value.Simple->redirects == 0 && command->redirects == 0 && command->value.Simple->redirects == 0 &&
((command->flags & CMD_TIME_PIPELINE) == 0) && ((command->flags & CMD_TIME_PIPELINE) == 0) &&
((command->flags & CMD_INVERT_RETURN) == 0)); ((command->flags & CMD_INVERT_RETURN) == 0));
@@ -134,6 +131,8 @@ optimize_subshell_command (command)
{ {
if (running_trap == 0 && if (running_trap == 0 &&
command->type == cm_simple && command->type == cm_simple &&
signal_is_trapped (EXIT_TRAP) == 0 &&
signal_is_trapped (ERROR_TRAP) == 0 &&
any_signals_trapped () < 0 && any_signals_trapped () < 0 &&
command->redirects == 0 && command->value.Simple->redirects == 0 && command->redirects == 0 && command->value.Simple->redirects == 0 &&
((command->flags & CMD_TIME_PIPELINE) == 0) && ((command->flags & CMD_TIME_PIPELINE) == 0) &&
+7 -1
View File
@@ -181,6 +181,7 @@ read_builtin (list)
int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2; int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul; int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
int raw, edit, nchars, silent, have_timeout, ignore_delim, fd, lastsig, t_errno; int raw, edit, nchars, silent, have_timeout, ignore_delim, fd, lastsig, t_errno;
int mb_cur_max;
unsigned int tmsec, tmusec; unsigned int tmsec, tmusec;
long ival, uval; long ival, uval;
intmax_t intval; intmax_t intval;
@@ -235,6 +236,7 @@ read_builtin (list)
rlind = 0; rlind = 0;
#endif #endif
mb_cur_max = MB_CUR_MAX;
tmsec = tmusec = 0; /* no timeout */ tmsec = tmusec = 0; /* no timeout */
nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0; nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0;
delim = '\n'; /* read until newline */ delim = '\n'; /* read until newline */
@@ -664,7 +666,11 @@ add_char:
CHECK_ALRM; CHECK_ALRM;
#if defined (HANDLE_MULTIBYTE) #if defined (HANDLE_MULTIBYTE)
if (nchars > 0 && MB_CUR_MAX > 1 && is_basic (c) == 0) # if 0
if (nchars > 0 && mb_cur_max > 1 && is_basic (c) == 0)
# else
if (mb_cur_max > 1 && is_basic (c) == 0)
# endif
{ {
input_string[i] = '\0'; /* for simplicity and debugging */ input_string[i] = '\0'; /* for simplicity and debugging */
i += read_mbchar (fd, input_string, i, c, unbuffered_read); i += read_mbchar (fd, input_string, i, c, unbuffered_read);
+4
View File
@@ -98,6 +98,7 @@ static int display_traps __P((WORD_LIST *));
#define IGNORE 2 /* Ignore this signal. */ #define IGNORE 2 /* Ignore this signal. */
extern int posixly_correct, subshell_environment; extern int posixly_correct, subshell_environment;
extern int sourcelevel, running_trap;
int int
trap_builtin (list) trap_builtin (list)
@@ -212,6 +213,9 @@ trap_builtin (list)
was SIG_IGN? */ was SIG_IGN? */
if (interactive) if (interactive)
set_signal_handler (SIGINT, sigint_sighandler); set_signal_handler (SIGINT, sigint_sighandler);
/* special cases for interactive == 0 */
else if (interactive_shell && (sourcelevel||running_trap))
set_signal_handler (SIGINT, sigint_sighandler);
else else
set_signal_handler (SIGINT, termsig_sighandler); set_signal_handler (SIGINT, termsig_sighandler);
break; break;
+1 -1
View File
@@ -90,7 +90,7 @@ reader_loop ()
/* XXX - why do we set this every time through the loop? And why do /* XXX - why do we set this every time through the loop? And why do
it if SIGINT is trapped in an interactive shell? */ it if SIGINT is trapped in an interactive shell? */
if (interactive_shell && signal_is_ignored (SIGINT) == 0) if (interactive_shell && signal_is_ignored (SIGINT) == 0 && signal_is_trapped (SIGINT) == 0)
set_signal_handler (SIGINT, sigint_sighandler); set_signal_handler (SIGINT, sigint_sighandler);
if (code != NOT_JUMPED) if (code != NOT_JUMPED)
+23 -6
View File
@@ -602,12 +602,13 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
{ {
pid_t paren_pid; pid_t paren_pid;
int s; int s;
char *p;
/* Fork a subshell, turn off the subshell bit, turn off job /* Fork a subshell, turn off the subshell bit, turn off job
control and call execute_command () on the command again. */ control and call execute_command () on the command again. */
line_number_for_err_trap = line_number; /* XXX - save value? */ line_number_for_err_trap = line_number; /* XXX - save value? */
tcmd = make_command_string (command); tcmd = make_command_string (command);
paren_pid = make_child (savestring (tcmd), asynchronous); paren_pid = make_child (p = savestring (tcmd), asynchronous);
if (user_subshell && signal_is_trapped (ERROR_TRAP) && if (user_subshell && signal_is_trapped (ERROR_TRAP) &&
signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0) signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
@@ -618,6 +619,9 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
if (paren_pid == 0) if (paren_pid == 0)
{ {
#if defined (JOB_CONTROL)
FREE (p); /* child doesn't use pointer */
#endif
/* We want to run the exit trap for forced {} subshells, and we /* We want to run the exit trap for forced {} subshells, and we
want to note this before execute_in_subshell modifies the want to note this before execute_in_subshell modifies the
COMMAND struct. Need to keep in mind that execute_in_subshell COMMAND struct. Need to keep in mind that execute_in_subshell
@@ -2279,7 +2283,7 @@ execute_coproc (command, pipe_in, pipe_out, fds_to_close)
int rpipe[2], wpipe[2], estat, invert; int rpipe[2], wpipe[2], estat, invert;
pid_t coproc_pid; pid_t coproc_pid;
Coproc *cp; Coproc *cp;
char *tcmd; char *tcmd, *p;
sigset_t set, oset; sigset_t set, oset;
/* XXX -- can be removed after changes to handle multiple coprocs */ /* XXX -- can be removed after changes to handle multiple coprocs */
@@ -2298,13 +2302,17 @@ execute_coproc (command, pipe_in, pipe_out, fds_to_close)
BLOCK_SIGNAL (SIGCHLD, set, oset); BLOCK_SIGNAL (SIGCHLD, set, oset);
coproc_pid = make_child (savestring (tcmd), 1); coproc_pid = make_child (p = savestring (tcmd), 1);
if (coproc_pid == 0) if (coproc_pid == 0)
{ {
close (rpipe[0]); close (rpipe[0]);
close (wpipe[1]); close (wpipe[1]);
#if defined (JOB_CONTROL)
FREE (p);
#endif
UNBLOCK_SIGNAL (oset); UNBLOCK_SIGNAL (oset);
estat = execute_in_subshell (command, 1, wpipe[0], rpipe[1], fds_to_close); estat = execute_in_subshell (command, 1, wpipe[0], rpipe[1], fds_to_close);
@@ -4138,7 +4146,9 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
if (async) if (async)
subshell_level++; /* not for pipes yet */ subshell_level++; /* not for pipes yet */
FREE (p); #if defined (JOB_CONTROL)
FREE (p); /* child doesn't use pointer */
#endif
} }
else else
{ {
@@ -4936,6 +4946,8 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var,
without_job_control (); without_job_control ();
set_sigchld_handler (); set_sigchld_handler ();
#else
without_job_control ();
#endif /* JOB_CONTROL */ #endif /* JOB_CONTROL */
set_sigint_handler (); set_sigint_handler ();
@@ -5166,7 +5178,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
struct fd_bitmap *fds_to_close; struct fd_bitmap *fds_to_close;
int cmdflags; int cmdflags;
{ {
char *pathname, *command, **args; char *pathname, *command, **args, *p;
int nofork, stdpath, result; int nofork, stdpath, result;
pid_t pid; pid_t pid;
SHELL_VAR *hookf; SHELL_VAR *hookf;
@@ -5176,6 +5188,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
nofork = (cmdflags & CMD_NO_FORK); /* Don't fork, just exec, if no pipes */ nofork = (cmdflags & CMD_NO_FORK); /* Don't fork, just exec, if no pipes */
pathname = words->word->word; pathname = words->word->word;
p = 0;
result = EXECUTION_SUCCESS; result = EXECUTION_SUCCESS;
#if defined (RESTRICTED_SHELL) #if defined (RESTRICTED_SHELL)
command = (char *)NULL; command = (char *)NULL;
@@ -5214,7 +5227,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE) if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE)
pid = 0; pid = 0;
else else
pid = make_child (savestring (command_line), async); pid = make_child (p = savestring (command_line), async);
if (pid == 0) if (pid == 0)
{ {
@@ -5226,6 +5239,10 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
CHECK_SIGTERM; CHECK_SIGTERM;
#if defined (JOB_CONTROL)
FREE (p);
#endif
/* restore_original_signals may have undone the work done /* restore_original_signals may have undone the work done
by make_child to ensure that SIGINT and SIGQUIT are ignored by make_child to ensure that SIGINT and SIGQUIT are ignored
in asynchronous children. */ in asynchronous children. */
+9 -6
View File
@@ -578,24 +578,23 @@ expcond ()
rval = cval = explor (); rval = cval = explor ();
if (curtok == QUES) /* found conditional expr */ if (curtok == QUES) /* found conditional expr */
{ {
readtok ();
if (curtok == 0 || curtok == COL)
evalerror (_("expression expected"));
if (cval == 0) if (cval == 0)
{ {
set_noeval = 1; set_noeval = 1;
noeval++; noeval++;
} }
readtok ();
if (curtok == 0 || curtok == COL)
evalerror (_("expression expected"));
val1 = EXP_HIGHEST (); val1 = EXP_HIGHEST ();
if (set_noeval) if (set_noeval)
noeval--; noeval--;
if (curtok != COL) if (curtok != COL)
evalerror (_("`:' expected for conditional expression")); evalerror (_("`:' expected for conditional expression"));
readtok ();
if (curtok == 0)
evalerror (_("expression expected"));
set_noeval = 0; set_noeval = 0;
if (cval) if (cval)
{ {
@@ -603,7 +602,11 @@ expcond ()
noeval++; noeval++;
} }
readtok ();
if (curtok == 0)
evalerror (_("expression expected"));
val2 = expcond (); val2 = expcond ();
if (set_noeval) if (set_noeval)
noeval--; noeval--;
rval = cval ? val1 : val2; rval = cval ? val1 : val2;
+3 -3
View File
@@ -1,6 +1,6 @@
/* unicode.c - functions to convert unicode characters */ /* unicode.c - functions to convert unicode characters */
/* Copyright (C) 2010-2015 Free Software Foundation, Inc. /* Copyright (C) 2010-2016 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell. This file is part of GNU Bash, the Bourne Again SHell.
@@ -219,12 +219,12 @@ u32toutf16 (c, s)
int l; int l;
l = 0; l = 0;
if (c < 0x0d800) if (c < 0x0d800 || (c >= 0x0e000 && c <= 0x0ffff))
{ {
s[0] = (unsigned short) (c & 0xFFFF); s[0] = (unsigned short) (c & 0xFFFF);
l = 1; l = 1;
} }
else if (c >= 0x0e000 && c <= 0x010ffff) else if (c >= 0x10000 && c <= 0x010ffff)
{ {
c -= 0x010000; c -= 0x010000;
s[0] = (unsigned short)((c >> 10) + 0xd800); s[0] = (unsigned short)((c >> 10) + 0xd800);
+7 -3
View File
@@ -170,7 +170,10 @@ alloc_pid_list ()
/* None of the newly allocated slots have process id's yet. */ /* None of the newly allocated slots have process id's yet. */
for (i = old; i < pid_list_size; i++) for (i = old; i < pid_list_size; i++)
pid_list[i].pid = NO_PID; {
pid_list[i].pid = NO_PID;
pid_list[i].status = pid_list[i].flags = 0;
}
} }
/* Return the offset within the PID_LIST array of an empty slot. This can /* Return the offset within the PID_LIST array of an empty slot. This can
@@ -399,8 +402,9 @@ cleanup_dead_jobs ()
for (i = 0; i < pid_list_size; i++) for (i = 0; i < pid_list_size; i++)
{ {
if ((pid_list[i].flags & PROC_RUNNING) == 0 && if (pid_list[i].pid != NO_PID &&
(pid_list[i].flags & PROC_NOTIFIED)) (pid_list[i].flags & PROC_RUNNING) == 0 &&
(pid_list[i].flags & PROC_NOTIFIED))
pid_list[i].pid = NO_PID; pid_list[i].pid = NO_PID;
} }
+65 -58
View File
@@ -1166,6 +1166,7 @@ string_extract_verbatim (string, slen, sindex, charlist, flags)
if ((flags & SX_NOCTLESC) == 0 && c == CTLESC) if ((flags & SX_NOCTLESC) == 0 && c == CTLESC)
{ {
i += 2; i += 2;
CHECK_STRING_OVERRUN (i, i, slen, c);
continue; continue;
} }
/* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
@@ -1174,6 +1175,7 @@ string_extract_verbatim (string, slen, sindex, charlist, flags)
else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL) else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL)
{ {
i += 2; i += 2;
CHECK_STRING_OVERRUN (i, i, slen, c);
continue; continue;
} }
@@ -2773,11 +2775,11 @@ list_string (string, separators, quoted)
extract a word, stopping at a separator extract a word, stopping at a separator
skip sequences of spc, tab, or nl as long as they are separators skip sequences of spc, tab, or nl as long as they are separators
This obeys the field splitting rules in Posix.2. */ This obeys the field splitting rules in Posix.2. */
slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 1; slen = STRLEN (string);
for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; ) for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
{ {
/* Don't need string length in ADVANCE_CHAR or string_extract_verbatim /* Don't need string length in ADVANCE_CHAR unless multibyte chars are
unless multibyte chars are possible. */ possible, but need it in string_extract_verbatim for bounds checking */
current_word = string_extract_verbatim (string, slen, &sindex, separators, xflags); current_word = string_extract_verbatim (string, slen, &sindex, separators, xflags);
if (current_word == 0) if (current_word == 0)
break; break;
@@ -2902,9 +2904,9 @@ get_word_from_string (stringp, separators, endptr)
This obeys the field splitting rules in Posix.2. */ This obeys the field splitting rules in Posix.2. */
sindex = 0; sindex = 0;
/* Don't need string length in ADVANCE_CHAR or string_extract_verbatim /* Don't need string length in ADVANCE_CHAR unless multibyte chars are
unless multibyte chars are possible. */ possible, but need it in string_extract_verbatim for bounds checking */
slen = (MB_CUR_MAX > 1) ? STRLEN (s) : 1; slen = STRLEN (s);
current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags); current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags);
/* Set ENDPTR to the first character after the end of the word. */ /* Set ENDPTR to the first character after the end of the word. */
@@ -5015,17 +5017,21 @@ parameter_brace_remove_pattern (varname, value, ind, patstr, rtype, quoted, flag
int rtype, quoted, flags; int rtype, quoted, flags;
{ {
int vtype, patspec, starsub; int vtype, patspec, starsub;
char *temp1, *val, *pattern; char *temp1, *val, *pattern, *oname;
SHELL_VAR *v; SHELL_VAR *v;
if (value == 0) if (value == 0)
return ((char *)NULL); return ((char *)NULL);
oname = this_command_name;
this_command_name = varname; this_command_name = varname;
vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val); vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
if (vtype == -1) if (vtype == -1)
return ((char *)NULL); {
this_command_name = oname;
return ((char *)NULL);
}
starsub = vtype & VT_STARSUB; starsub = vtype & VT_STARSUB;
vtype &= ~VT_STARSUB; vtype &= ~VT_STARSUB;
@@ -5079,6 +5085,8 @@ parameter_brace_remove_pattern (varname, value, ind, patstr, rtype, quoted, flag
break; break;
} }
this_command_name = oname;
FREE (pattern); FREE (pattern);
return temp1; return temp1;
} }
@@ -5285,18 +5293,22 @@ parameter_brace_transform (varname, value, ind, xform, rtype, quoted, flags)
int rtype, quoted, flags; int rtype, quoted, flags;
{ {
int vtype, xc; int vtype, xc;
char *temp1, *val; char *temp1, *val, *oname;
SHELL_VAR *v; SHELL_VAR *v;
xc = xform[0]; xc = xform[0];
if (value == 0 && xc != 'A' && xc != 'a') if (value == 0 && xc != 'A' && xc != 'a')
return ((char *)NULL); return ((char *)NULL);
oname = this_command_name;
this_command_name = varname; this_command_name = varname;
vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val); vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
if (vtype == -1) if (vtype == -1)
return ((char *)NULL); {
this_command_name = oname;
return ((char *)NULL);
}
/* check for valid values of xc */ /* check for valid values of xc */
switch (xc) switch (xc)
@@ -5308,6 +5320,7 @@ parameter_brace_transform (varname, value, ind, xform, rtype, quoted, flags)
case 'Q': /* quote reusably */ case 'Q': /* quote reusably */
break; break;
default: default:
this_command_name = oname;
return &expand_param_error; return &expand_param_error;
} }
@@ -5350,6 +5363,7 @@ parameter_brace_transform (varname, value, ind, xform, rtype, quoted, flags)
break; break;
} }
this_command_name = oname;
return temp1; return temp1;
} }
@@ -7631,17 +7645,21 @@ parameter_brace_patsub (varname, value, ind, patsub, quoted, pflags, flags)
int quoted, pflags, flags; int quoted, pflags, flags;
{ {
int vtype, mflags, starsub, delim; int vtype, mflags, starsub, delim;
char *val, *temp, *pat, *rep, *p, *lpatsub, *tt; char *val, *temp, *pat, *rep, *p, *lpatsub, *tt, *oname;
SHELL_VAR *v; SHELL_VAR *v;
if (value == 0) if (value == 0)
return ((char *)NULL); return ((char *)NULL);
this_command_name = varname; oname = this_command_name;
this_command_name = varname; /* error messages */
vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val); vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
if (vtype == -1) if (vtype == -1)
return ((char *)NULL); {
this_command_name = oname;
return ((char *)NULL);
}
starsub = vtype & VT_STARSUB; starsub = vtype & VT_STARSUB;
vtype &= ~VT_STARSUB; vtype &= ~VT_STARSUB;
@@ -7769,6 +7787,8 @@ parameter_brace_patsub (varname, value, ind, patsub, quoted, pflags, flags)
FREE (rep); FREE (rep);
free (lpatsub); free (lpatsub);
this_command_name = oname;
return temp; return temp;
} }
@@ -7825,17 +7845,21 @@ parameter_brace_casemod (varname, value, ind, modspec, patspec, quoted, flags)
int quoted, flags; int quoted, flags;
{ {
int vtype, starsub, modop, mflags, x; int vtype, starsub, modop, mflags, x;
char *val, *temp, *pat, *p, *lpat, *tt; char *val, *temp, *pat, *p, *lpat, *tt, *oname;
SHELL_VAR *v; SHELL_VAR *v;
if (value == 0) if (value == 0)
return ((char *)NULL); return ((char *)NULL);
oname = this_command_name;
this_command_name = varname; this_command_name = varname;
vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val); vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
if (vtype == -1) if (vtype == -1)
return ((char *)NULL); {
this_command_name = oname;
return ((char *)NULL);
}
starsub = vtype & VT_STARSUB; starsub = vtype & VT_STARSUB;
vtype &= ~VT_STARSUB; vtype &= ~VT_STARSUB;
@@ -7912,6 +7936,8 @@ parameter_brace_casemod (varname, value, ind, modspec, patspec, quoted, flags)
FREE (pat); FREE (pat);
free (lpat); free (lpat);
this_command_name = oname;
return temp; return temp;
} }
@@ -9779,7 +9805,9 @@ finished_with_string:
{ {
istring[0] = CTLNUL; istring[0] = CTLNUL;
istring[1] = '\0'; istring[1] = '\0';
tword = make_bare_word (istring); tword = alloc_word_desc ();
tword->word = istring;
istring = 0; /* avoid later free() */
tword->flags |= W_HASQUOTEDNULL; /* XXX */ tword->flags |= W_HASQUOTEDNULL; /* XXX */
list = make_word_list (tword, (WORD_LIST *)NULL); list = make_word_list (tword, (WORD_LIST *)NULL);
if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
@@ -9792,22 +9820,16 @@ finished_with_string:
null arguments */ null arguments */
else if (quoted_state == UNQUOTED || quoted_dollar_at) else if (quoted_state == UNQUOTED || quoted_dollar_at)
list = (WORD_LIST *)NULL; list = (WORD_LIST *)NULL;
#if 0
else
{
tword = make_bare_word (istring);
if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
tword->flags |= W_QUOTED;
list = make_word_list (tword, (WORD_LIST *)NULL);
}
#else
else else
list = (WORD_LIST *)NULL; list = (WORD_LIST *)NULL;
#endif
} }
else if (word->flags & W_NOSPLIT) else if (word->flags & W_NOSPLIT)
{ {
tword = make_bare_word (istring); tword = alloc_word_desc ();
tword->word = istring;
if (had_quoted_null && QUOTED_NULL (istring))
tword->flags |= W_HASQUOTEDNULL;
istring = 0; /* avoid later free() */
if (word->flags & W_ASSIGNMENT) if (word->flags & W_ASSIGNMENT)
tword->flags |= W_ASSIGNMENT; /* XXX */ tword->flags |= W_ASSIGNMENT; /* XXX */
if (word->flags & W_COMPASSIGN) if (word->flags & W_COMPASSIGN)
@@ -9820,8 +9842,6 @@ finished_with_string:
tword->flags |= W_NOEXPAND; /* XXX */ tword->flags |= W_NOEXPAND; /* XXX */
if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
tword->flags |= W_QUOTED; tword->flags |= W_QUOTED;
if (had_quoted_null && QUOTED_NULL (istring))
tword->flags |= W_HASQUOTEDNULL;
list = make_word_list (tword, (WORD_LIST *)NULL); list = make_word_list (tword, (WORD_LIST *)NULL);
} }
else else
@@ -9855,47 +9875,36 @@ finished_with_string:
double-quoted $@ while expanding it. */ double-quoted $@ while expanding it. */
else if (has_dollar_at && quoted_dollar_at == 0 && ifs_chars && quoted == 0 && (word->flags & W_NOSPLIT2)) else if (has_dollar_at && quoted_dollar_at == 0 && ifs_chars && quoted == 0 && (word->flags & W_NOSPLIT2))
{ {
tword = alloc_word_desc ();
/* Only split and rejoin if we have to */ /* Only split and rejoin if we have to */
if (*ifs_chars && *ifs_chars != ' ') if (*ifs_chars && *ifs_chars != ' ')
{ {
list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1); list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
tstring = string_list (list); tword->word = string_list (list);
} }
else else
tstring = istring; tword->word = istring;
tword = make_bare_word (tstring); if (had_quoted_null && QUOTED_NULL (istring))
if (tstring != istring) tword->flags |= W_HASQUOTEDNULL; /* XXX */
free (tstring); if (tword->word != istring)
free (istring);
istring = 0; /* avoid later free() */
goto set_word_flags; goto set_word_flags;
} }
/* This is the attempt to make $* in an assignment context (a=$*) and
array variables subscripted with * in an assignment context (a=${foo[*]})
behave similarly. It has side effects that, though they increase
compatibility with other shells, are not backwards compatible. */
#if 0
else if (has_dollar_at && quoted == 0 && ifs_chars && (word->flags & W_ASSIGNRHS))
{
tword = make_bare_word (istring);
goto set_word_flags;
}
#endif
else if (has_dollar_at && ifs_chars) else if (has_dollar_at && ifs_chars)
list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1); list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
else else
{ {
#if 0 tword = alloc_word_desc ();
/* XXX might want to use *expanded_something == 0 instead of
local_expanded here */
if (local_expanded == 0 && has_quoted_ifs)
#else
if (expanded_something && *expanded_something == 0 && has_quoted_ifs) if (expanded_something && *expanded_something == 0 && has_quoted_ifs)
#endif tword->word = remove_quoted_ifs (istring);
{
tword = alloc_word_desc ();
tword->word = remove_quoted_ifs (istring);
}
else else
tword = make_bare_word (istring); tword->word = istring;
if (had_quoted_null && QUOTED_NULL (istring))
tword->flags |= W_HASQUOTEDNULL; /* XXX */
if (tword->word != istring)
free (istring);
istring = 0; /* avoid later free() */
set_word_flags: set_word_flags:
if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED)) if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
tword->flags |= W_QUOTED; tword->flags |= W_QUOTED;
@@ -9909,8 +9918,6 @@ set_word_flags:
tword->flags |= W_NOBRACE; tword->flags |= W_NOBRACE;
if (word->flags & W_NOEXPAND) if (word->flags & W_NOEXPAND)
tword->flags |= W_NOEXPAND; tword->flags |= W_NOEXPAND;
if (had_quoted_null && QUOTED_NULL (istring))
tword->flags |= W_HASQUOTEDNULL; /* XXX */
list = make_word_list (tword, (WORD_LIST *)NULL); list = make_word_list (tword, (WORD_LIST *)NULL);
} }
} }
+6 -2
View File
@@ -627,8 +627,12 @@ unary_test (op, arg)
if (v == 0 && valid_array_reference (arg, 0)) if (v == 0 && valid_array_reference (arg, 0))
{ {
char *t; char *t;
t = array_value (arg, 0, 0, (int *)0, (arrayind_t *)0); int rtype, ret;
return (t ? TRUE : FALSE); t = array_value (arg, 0, 0, &rtype, (arrayind_t *)0);
ret = t ? TRUE : FALSE;
if (rtype > 0) /* subscript is * or @ */
free (t);
return ret;
} }
else if (v && invisible_p (v) == 0 && array_p (v)) else if (v && invisible_p (v) == 0 && array_p (v))
{ {
+2
View File
@@ -494,6 +494,8 @@ first_pending_trap ()
return -1; return -1;
} }
/* Return > 0 if any of the "real" signals (not fake signals like EXIT) are
trapped. */
int int
any_signals_trapped () any_signals_trapped ()
{ {