mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-28 16:09:51 +02:00
commit bash-20180406 snapshot
This commit is contained in:
@@ -15137,3 +15137,63 @@ lib/readline/bind.c
|
||||
to accommodate symbolic key sequences; should be a no-op for `raw'
|
||||
key sequences such as the arrow key seqeunces from terminfo. Change
|
||||
from Koichi Murase <myoga.murase@gmail.com>
|
||||
|
||||
4/2
|
||||
---
|
||||
jobs.c
|
||||
- wait_for: when setting the SIGINT signal handler to wait_sigint_handler
|
||||
make sure we're not setting old_sigint_handler recursively, as we
|
||||
can when running an external command in a trap we took after a
|
||||
command exited due to SIGINT. We don't want to overwrite
|
||||
old_sigint_handler here. Fixes bug reported by Dr. Werner Fink
|
||||
<werner@suse.de>
|
||||
|
||||
execute_cmd.c
|
||||
- execute_disk_command: when there is a command_not_found_hook, make
|
||||
sure the subshell turns off job control before running it, in case
|
||||
it runs processes. We don't want it to manipulate process groups.
|
||||
Fixes bug reported by ÐиÑиллов Ðима <dk.1997-fast@yandex.ru>
|
||||
- execute_command_internal: make sure the command run by the `command'
|
||||
builtin doesn't cause the ERR trap to be executed; wait for the
|
||||
status to be returned by the command builtin. Fixes bug reported by
|
||||
Martijn Dekker <martijn@inlv.org>
|
||||
|
||||
4/4
|
||||
---
|
||||
subst.c
|
||||
- process_substitute: handle longjmp back to top_level and function
|
||||
returns (return_catch) in the child process, like command
|
||||
substitution, so we don't longjmp back to some arbitrary spot from
|
||||
the `exit' or `return' builtins, or on an expansion error, like
|
||||
the command timing code. Fixes bug reported by Basin Ilya
|
||||
<basinilya@gmail.com>
|
||||
|
||||
4/6
|
||||
---
|
||||
parse.y
|
||||
- read_token_word: when reading a matched pair of backquotes as part
|
||||
of a word, treat it as quoted so the characters are read as a single
|
||||
word, but do not let the presence of the backquote mark the word as
|
||||
quoted. Fixes here-document delimiter bug reported by Denys Vlasenko
|
||||
<dvlasenk@redhat.com>
|
||||
|
||||
4/7
|
||||
---
|
||||
execute_cmd.c
|
||||
- execute_case_command: call quote_string_for_globbing with the
|
||||
QGLOB_CTLESC flag for both quoted and unquoted words, so it will
|
||||
remove CTLESC/CTLESC in all cases while converting other quoted
|
||||
characters to use a preceding backslash. Bug reported by
|
||||
Martijn Dekker <martijn@inlv.org>
|
||||
|
||||
4/9
|
||||
---
|
||||
smatch.c
|
||||
- posix_cclass_only: helper function that checks whether a pattern has
|
||||
only posix single-byte character classes ([:alpha:], etc.) or has
|
||||
none at all
|
||||
- xstrmatch: if running in a multibyte locale, make sure to short-
|
||||
circuit to the single-byte matching code only if there are no
|
||||
unrecognized character class names, since the wide character ctype
|
||||
functions allow locales to define their own character class names
|
||||
(e.g., "hyphen"). Fixes issue reported by yangyajing <yyj_cqu@163.com>
|
||||
|
||||
@@ -903,6 +903,7 @@ tests/case.tests f
|
||||
tests/case.right f
|
||||
tests/case1.sub f
|
||||
tests/case2.sub f
|
||||
tests/case3.sub f
|
||||
tests/casemod.tests f
|
||||
tests/casemod.right f
|
||||
tests/comsub.tests f
|
||||
@@ -1058,6 +1059,7 @@ tests/heredoc.right f
|
||||
tests/heredoc1.sub f
|
||||
tests/heredoc2.sub f
|
||||
tests/heredoc3.sub f
|
||||
tests/heredoc4.sub f
|
||||
tests/herestr.tests f
|
||||
tests/herestr.right f
|
||||
tests/herestr1.sub f
|
||||
|
||||
+20
-7
@@ -873,8 +873,13 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||
}
|
||||
|
||||
/* 2009/02/13 -- pipeline failure is processed elsewhere. This handles
|
||||
only the failure of a simple command. */
|
||||
if (was_error_trap && ignore_return == 0 && invert == 0 && pipe_in == NO_PIPE && pipe_out == NO_PIPE && exec_result != EXECUTION_SUCCESS)
|
||||
only the failure of a simple command. We don't want to run the error
|
||||
trap if the command run by the `command' builtin fails; we want to
|
||||
defer that until the command builtin itself returns failure. */
|
||||
if (was_error_trap && ignore_return == 0 && invert == 0 &&
|
||||
pipe_in == NO_PIPE && pipe_out == NO_PIPE &&
|
||||
(command->value.Simple->flags & CMD_COMMAND_BUILTIN) == 0 &&
|
||||
exec_result != EXECUTION_SUCCESS)
|
||||
{
|
||||
last_command_exit_value = exec_result;
|
||||
line_number = line_number_for_err_trap;
|
||||
@@ -1421,6 +1426,7 @@ time_command (command, asynchronous, pipe_in, pipe_out, fds_to_close)
|
||||
else
|
||||
time_format = BASH_TIMEFORMAT;
|
||||
}
|
||||
|
||||
if (time_format && *time_format)
|
||||
print_formatted_time (stderr, time_format, rs, rsf, us, usf, ss, ssf, cpu);
|
||||
|
||||
@@ -3464,12 +3470,15 @@ execute_case_command (case_command)
|
||||
|
||||
if (es && es->word && es->word->word && *(es->word->word))
|
||||
{
|
||||
/* Convert quoted null strings into empty strings. */
|
||||
qflags = QGLOB_CVTNULL;
|
||||
|
||||
/* We left CTLESC in place quoting CTLESC after the call to
|
||||
expand_word_leave_quoted; tell quote_string_for_globbing to
|
||||
remove those here */
|
||||
if ((list->word->flags & W_QUOTED) == 0)
|
||||
qflags |= QGLOB_CTLESC;
|
||||
remove those here. This works for both unquoted portions of
|
||||
the word (which call quote_escapes) and quoted portions
|
||||
(which call quote_string). */
|
||||
qflags |= QGLOB_CTLESC;
|
||||
pattern = quote_string_for_globbing (es->word->word, qflags);
|
||||
}
|
||||
else
|
||||
@@ -5375,9 +5384,13 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
|
||||
exit (EX_NOTFOUND); /* Posix.2 says the exit status is 127 */
|
||||
}
|
||||
|
||||
/* We don't want to manage process groups for processes we start
|
||||
from here, so we turn off job control and don't attempt to
|
||||
manipulate the terminal's process group. */
|
||||
without_job_control ();
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
/* May need to reinitialize more of the job control state here. */
|
||||
kill_current_pipeline ();
|
||||
set_sigchld_handler ();
|
||||
#endif
|
||||
|
||||
wl = make_word_list (make_word (NOTFOUND_HOOK), words);
|
||||
|
||||
@@ -35,6 +35,15 @@ struct func_array_state
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Placeholder for later expansion to include more execution state */
|
||||
/* XXX - watch out for pid_t */
|
||||
struct execstate
|
||||
{
|
||||
pid_t pid;
|
||||
int subshell_env;
|
||||
};
|
||||
|
||||
|
||||
/* Variables delared in execute_cmd.c, used by many other files */
|
||||
extern int return_catch_flag;
|
||||
extern int return_catch_value;
|
||||
|
||||
@@ -2723,7 +2723,17 @@ wait_for (pid)
|
||||
wait_sigint_received = child_caught_sigint = 0;
|
||||
if (job_control == 0 || (subshell_environment&SUBSHELL_COMSUB))
|
||||
{
|
||||
old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
|
||||
SigHandler *temp_sigint_handler;
|
||||
|
||||
temp_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
|
||||
if (temp_sigint_handler == wait_sigint_handler)
|
||||
{
|
||||
#if defined (DEBUG)
|
||||
internal_warning ("wait_for: recursively setting old_sigint_handler to wait_sigint_handler: running_trap = %d", running_trap);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
old_sigint_handler = temp_sigint_handler;
|
||||
waiting_for_child = 0;
|
||||
if (old_sigint_handler == SIG_IGN)
|
||||
set_signal_handler (SIGINT, old_sigint_handler);
|
||||
|
||||
+45
-1
@@ -380,6 +380,50 @@ is_wcclass (wc, name)
|
||||
return (iswctype (wc, desc));
|
||||
}
|
||||
|
||||
/* Return 1 if there are no char class [:class:] expressions (degenerate case)
|
||||
or only posix-specified (C locale supported) char class expressions in
|
||||
PATTERN. These are the ones where it's safe to punt to the single-byte
|
||||
code, since wide character support allows locale-defined char classes.
|
||||
This only uses single-byte code, but is only needed to support multibyte
|
||||
locales. */
|
||||
static int
|
||||
posix_cclass_only (pattern)
|
||||
char *pattern;
|
||||
{
|
||||
char *p, *p1;
|
||||
char cc[16]; /* sufficient for all valid posix char class names */
|
||||
enum char_class valid;
|
||||
|
||||
p = pattern;
|
||||
while (p = strchr (p, '['))
|
||||
{
|
||||
if (p[1] != ':')
|
||||
{
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
p += 2; /* skip past "[:" */
|
||||
/* Find end of char class expression */
|
||||
for (p1 = p; *p1; p1++)
|
||||
if (*p1 == ':' && p1[1] == ']')
|
||||
break;
|
||||
if (*p1 == 0) /* no char class expression found */
|
||||
break;
|
||||
/* Find char class name and validate it against posix char classes */
|
||||
if ((p1 - p) >= sizeof (cc))
|
||||
return 0;
|
||||
bcopy (p, cc, p1 - p);
|
||||
cc[p1 - p] = '\0';
|
||||
valid = is_valid_cclass (cc);
|
||||
if (valid == CC_NO_CLASS)
|
||||
return 0; /* found unrecognized char class name */
|
||||
|
||||
p = p1 + 2; /* found posix char class name */
|
||||
}
|
||||
|
||||
return 1; /* no char class names or only posix */
|
||||
}
|
||||
|
||||
/* Now include `sm_loop.c' for multibyte characters. */
|
||||
#define FOLD(c) ((flags & FNM_CASEFOLD) && iswupper (c) ? towlower (c) : (c))
|
||||
#define FCT internal_wstrmatch
|
||||
@@ -419,7 +463,7 @@ xstrmatch (pattern, string, flags)
|
||||
if (MB_CUR_MAX == 1)
|
||||
return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
|
||||
|
||||
if (mbsmbchar (string) == 0 && mbsmbchar (pattern) == 0)
|
||||
if (mbsmbchar (string) == 0 && mbsmbchar (pattern) == 0 && posix_cclass_only (pattern) )
|
||||
return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags));
|
||||
|
||||
n = xdupmbstowcs (&wpattern, NULL, pattern);
|
||||
|
||||
@@ -1149,6 +1149,7 @@ and store the definition.
|
||||
.B call\-last\-kbd\-macro (C\-x e)
|
||||
Re-execute the last keyboard macro defined, by making the characters
|
||||
in the macro appear as if typed at the keyboard.
|
||||
.TP
|
||||
.B print\-last\-kbd\-macro ()
|
||||
Print the last keyboard macro defined in a format suitable for the
|
||||
\fIinputrc\fP file.
|
||||
|
||||
@@ -4946,7 +4946,8 @@ read_token_word (character)
|
||||
strcpy (token + token_index, ttok);
|
||||
token_index += ttoklen;
|
||||
all_digit_token = 0;
|
||||
quoted = 1;
|
||||
if (character != '`')
|
||||
quoted = 1;
|
||||
dollar_present |= (character == '"' && strchr (ttok, '$') != 0);
|
||||
FREE (ttok);
|
||||
goto next_character;
|
||||
|
||||
@@ -34,6 +34,7 @@ extern char *glob_error_return;
|
||||
#define QGLOB_FILENAME 0x02 /* do correct quoting for matching filenames */
|
||||
#define QGLOB_REGEXP 0x04 /* quote an ERE for regcomp/regexec */
|
||||
#define QGLOB_CTLESC 0x08 /* turn CTLESC CTLESC into CTLESC for BREs */
|
||||
#define QGLOB_DEQUOTE 0x10 /* like dequote_string but quote glob chars */
|
||||
|
||||
#if defined (EXTENDED_GLOB)
|
||||
/* Flags to OR with other flag args to strmatch() to enabled the extended
|
||||
|
||||
@@ -5713,7 +5713,7 @@ process_substitute (string, open_for_read_in_child)
|
||||
int open_for_read_in_child;
|
||||
{
|
||||
char *pathname;
|
||||
int fd, result;
|
||||
int fd, result, rc, function_value;
|
||||
pid_t old_pid, pid;
|
||||
#if defined (HAVE_DEV_FD)
|
||||
int parent_pipe_fd, child_pipe_fd;
|
||||
@@ -5903,18 +5903,41 @@ process_substitute (string, open_for_read_in_child)
|
||||
|
||||
remove_quoted_escapes (string);
|
||||
|
||||
subshell_level++;
|
||||
result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
|
||||
/* leave subshell level intact for any exit trap */
|
||||
/* Give process substitution a place to jump back to on failure,
|
||||
so we don't go back up to main (). */
|
||||
result = setjmp_nosigs (top_level);
|
||||
|
||||
/* If we're running a process substitution inside a shell function,
|
||||
trap `return' so we don't return from the function in the subshell
|
||||
and go off to never-never land. */
|
||||
if (result == 0 && return_catch_flag)
|
||||
function_value = setjmp_nosigs (return_catch);
|
||||
else
|
||||
function_value = 0;
|
||||
|
||||
if (result == ERREXIT)
|
||||
rc = last_command_exit_value;
|
||||
else if (result == EXITPROG)
|
||||
rc = last_command_exit_value;
|
||||
else if (result)
|
||||
rc = EXECUTION_FAILURE;
|
||||
else if (function_value)
|
||||
rc = return_catch_value;
|
||||
else
|
||||
{
|
||||
subshell_level++;
|
||||
rc = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
|
||||
/* leave subshell level intact for any exit trap */
|
||||
}
|
||||
|
||||
#if !defined (HAVE_DEV_FD)
|
||||
/* Make sure we close the named pipe in the child before we exit. */
|
||||
close (open_for_read_in_child ? 0 : 1);
|
||||
#endif /* !HAVE_DEV_FD */
|
||||
|
||||
last_command_exit_value = result;
|
||||
result = run_exit_trap ();
|
||||
exit (result);
|
||||
last_command_exit_value = rc;
|
||||
rc = run_exit_trap ();
|
||||
exit (rc);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
#endif /* PROCESS_SUBSTITUTION */
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
@@ -36,3 +36,19 @@ ok 5
|
||||
ok 6
|
||||
ok 7
|
||||
ok 8
|
||||
--- testing: soh
|
||||
ok1ok2ok3ok4ok5
|
||||
ok1ok2ok3ok4ok5
|
||||
ok1ok2ok3ok4ok5
|
||||
ok1ok2ok3ok4ok5
|
||||
ok1ok2ok3ok4ok5
|
||||
ok1ok2ok3ok4ok5
|
||||
ok1ok2ok3ok4ok5
|
||||
--- testing: stx
|
||||
ok1ok2ok3ok4ok5
|
||||
ok1ok2ok3ok4ok5
|
||||
ok1ok2ok3ok4ok5
|
||||
ok1ok2ok3ok4ok5
|
||||
ok1ok2ok3ok4ok5
|
||||
ok1ok2ok3ok4ok5
|
||||
ok1ok2ok3ok4ok5
|
||||
|
||||
@@ -52,3 +52,4 @@ case " " in ( [" "] ) echo ok;; ( * ) echo no;; esac
|
||||
# tests of quote removal and pattern matching
|
||||
${THIS_SH} ./case1.sub
|
||||
${THIS_SH} ./case2.sub
|
||||
${THIS_SH} ./case3.sub
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
|
||||
testmatch() {
|
||||
case $1 in
|
||||
( $2 ) printf ok1 ;;
|
||||
( * ) printf fail1 ;;
|
||||
esac
|
||||
case $1,$2 in
|
||||
( $2,"$2" ) printf ok2 ;;
|
||||
( * ) printf fail2 ;;
|
||||
esac
|
||||
case $1, in
|
||||
( $2, ) printf ok3 ;;
|
||||
( * ) printf fail3 ;;
|
||||
esac
|
||||
case ,$2 in
|
||||
( ,"$2" ) printf ok4 ;;
|
||||
( * ) printf fail4 ;;
|
||||
esac
|
||||
case "$1,$2" in
|
||||
( $2,"$2" ) printf ok5 ;;
|
||||
( * ) printf fail5 ;;
|
||||
esac
|
||||
echo
|
||||
}
|
||||
|
||||
for c in $'\1' $'\2'; do
|
||||
echo -n "--- testing: "
|
||||
echo "$c" | od -t a | awk 'NR==1 { print $2 } '
|
||||
testmatch "${c}" "\\${c}"
|
||||
testmatch "${c}x" "\\${c}\\x" # bash-git fails case 2 and 5 for $'\1'
|
||||
testmatch "${c}x" "${c}\\x"
|
||||
testmatch "${c}x" "${c}x"
|
||||
testmatch "${c}x" "\\${c}x"
|
||||
testmatch "x${c}" "\\x\\${c}"
|
||||
testmatch "x${c}" "x\\${c}"
|
||||
done
|
||||
@@ -84,6 +84,14 @@ hello
|
||||
end hello<NL>\END
|
||||
./heredoc3.sub: line 85: warning: here-document at line 83 delimited by end-of-file (wanted `EOF')
|
||||
./heredoc3.sub: line 86: syntax error: unexpected end of file
|
||||
heredoc1
|
||||
EOF
|
||||
Ok:0
|
||||
argv[1] = <onetwo>
|
||||
argv[2] = <threefour>
|
||||
argv[1] = <two>
|
||||
argv[2] = <threefi>
|
||||
argv[3] = <ve>
|
||||
comsub here-string
|
||||
./heredoc.tests: line 105: warning: here-document at line 103 delimited by end-of-file (wanted `EOF')
|
||||
hi
|
||||
|
||||
+1
-1
@@ -90,8 +90,8 @@ ${THIS_SH} ./heredoc1.sub
|
||||
|
||||
# test heredocs in command substitutions
|
||||
${THIS_SH} ./heredoc2.sub
|
||||
|
||||
${THIS_SH} ./heredoc3.sub
|
||||
${THIS_SH} ./heredoc4.sub
|
||||
|
||||
echo $(
|
||||
cat <<< "comsub here-string"
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
cat <<EO`true`F
|
||||
heredoc1
|
||||
EO`false`F
|
||||
EO`true`F
|
||||
echo Ok:$?
|
||||
|
||||
one=one
|
||||
four=four
|
||||
five='fi ve'
|
||||
|
||||
recho $one`echo two three`$four
|
||||
recho `echo two three`$five
|
||||
+5
-5
@@ -16,11 +16,11 @@ Waiting for job 6
|
||||
job 6 returns 0
|
||||
Waiting for job 7
|
||||
job 7 returns 0
|
||||
[1] Running sleep 5 &
|
||||
[2] Running sleep 5 &
|
||||
[3] Running sleep 5 &
|
||||
[4]- Running sleep 5 &
|
||||
[5]+ Running ( sleep 5; exit 4 ) &
|
||||
[1] Running sleep 2 &
|
||||
[2] Running sleep 2 &
|
||||
[3] Running sleep 2 &
|
||||
[4]- Running sleep 2 &
|
||||
[5]+ Running ( sleep 2; exit 4 ) &
|
||||
4
|
||||
0
|
||||
i killed it
|
||||
|
||||
@@ -64,6 +64,14 @@ after while
|
||||
before false in trap2a.sub
|
||||
after false in trap2a.sub
|
||||
command substitution
|
||||
ERRTRAP
|
||||
ERRTRAP
|
||||
bar
|
||||
ERRTRAP
|
||||
ERRTRAP
|
||||
ERRTRAP
|
||||
ERRTRAP
|
||||
ERRTRAP
|
||||
+[6] echo 1
|
||||
1
|
||||
+[7] echo 2
|
||||
|
||||
@@ -23,3 +23,27 @@ echo after while
|
||||
./trap2a.sub
|
||||
|
||||
echo $(false ; echo command substitution)
|
||||
|
||||
# test behavior of failed commands following `command' builtin
|
||||
command false
|
||||
|
||||
(command false)
|
||||
command false | echo bar
|
||||
|
||||
(false)
|
||||
|
||||
exit 42 | command false
|
||||
|
||||
command command command false
|
||||
|
||||
unset FALSE
|
||||
if [ -x /bin/false ]; then
|
||||
FALSE=/bin/false
|
||||
elif [ -x /usr/bin/false ]; then
|
||||
FALSE=/usr/bin/false
|
||||
else
|
||||
FALSE='command false'
|
||||
fi
|
||||
|
||||
command $FALSE
|
||||
command command command $FALSE
|
||||
|
||||
Reference in New Issue
Block a user