whether or not the word consists of all digits. This allows function
names to consist solely of digits when not in posix mode. From a
report by Andrey Butirsky <butirsky@gmail.com>
+
+ 1/22
+ ----
+bashline.c
+ - initialize_readline: only unbind ^E in vi_movement_keymap if it's
+ still bound to the default rl_emacs_editing_mode. Fixes bug
+ reported by Greg Bell <gbell_spamless@yahoo.com>
+
+ 1/23
+ ----
+builtins/shopt.def
+ - we need the extern declaration for syslog_history if SYSLOG_HISTORY
+ is defined, since it's used even if SYSLOG_SHOPT is not defined
+
+ 1/25
+ ----
+command.h
+ - CMD_TRY_OPTIMIZING: new command flag, means this (simple) command is
+ a candidate for fork optimization (suppression)
+
+builtins/evalstring.c
+ - can_optimize_connection: new function, takes an AND_OR list (&& or
+ ||) from parse_and_execute, makes sure it's the last in a possibly
+ multi-command list, and returns non-zero if it's a simple command,
+ indicating that it's a candidate for fork optimization.
+ - parse_and_execute: if we have a cm_connection command, call
+ can_optimize_connection to determine if it's a suitable candidate
+ and set CMD_TRY_OPTIMIZING if that returns non-zero
+ - optimize_fork: don't bother unless the rhs of the && or || command
+ has the CMD_TRY_OPTIMIZING flag set. These fix the bug reported by
+ Brad Spencer <bspencer@blackberry.com>
+
+execute_cmd.c
+ - execute_connection: case AND_AND and OR_OR: call optimize_fork on
+ the right side of the command before executing `second'. This will
+ safely restore the fork optimization we removed from
+ parse_and_execute()
+
+builtins/complete.def
+ - build_actions: make sure the function name argument to -F is a
+ valid shell function name: it doesn't contain any invalid posix-
+ mode characters and doesn't contain any shell break characters that
+ would need to be quoted when defining a function. Fixes issue
+ reported by Great Big Dot <greatbigdot@gmail.com>
if (func == rl_vi_editing_mode)
rl_unbind_key_in_map (CTRL('M'), emacs_meta_keymap);
#if defined (VI_MODE)
- rl_unbind_key_in_map (CTRL('E'), vi_movement_keymap);
+ kseq[0] = CTRL('E');
+ func = rl_function_of_keyseq (kseq, vi_movement_keymap, (int *)NULL);
+ if (func == rl_emacs_editing_mode)
+ rl_unbind_key_in_map (CTRL('E'), vi_movement_keymap);
#endif
#if defined (BRACE_COMPLETION)
extern void parse_and_execute_cleanup __P((int));
extern int parse_string __P((char *, const char *, int, char **));
extern int should_suppress_fork __P((COMMAND *));
+extern int can_optimize_connection __P((COMMAND *));
extern void optimize_fork __P((COMMAND *));
extern void optimize_subshell_command __P((COMMAND *));
{
int opt, ind, opt_given;
unsigned long acts, copts;
+ WORD_DESC w;
acts = copts = (unsigned long)0L;
opt_given = 0;
return (EX_USAGE);
}
case 'F':
- Farg = list_optarg;
+ w.word = Farg = list_optarg;
+ w.flags = 0;
+ if (check_identifier (&w, posixly_correct) == 0 || strcspn (Farg, shell_break_chars))
+ {
+ sh_invalidid (Farg);
+ return (EX_USAGE);
+ }
break;
case 'G':
Garg = list_optarg;
((command->flags & CMD_INVERT_RETURN) == 0));
}
+int
+can_optimize_connection (command)
+ COMMAND *command;
+{
+ return (*bash_input.location.string == '\0' &&
+ (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR) &&
+ command->value.Connection->second->type == cm_simple);
+}
+
void
optimize_fork (command)
COMMAND *command;
{
if (command->type == cm_connection &&
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR) &&
+ (command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) &&
should_suppress_fork (command->value.Connection->second))
{
command->value.Connection->second->flags |= CMD_NO_FORK;
command->flags |= CMD_NO_FORK;
command->value.Simple->flags |= CMD_NO_FORK;
}
- else if (command->type == cm_connection)
- optimize_fork (command);
+
+ /* Can't optimize forks out here execept for simple commands.
+ This knows that the parser sets up commands as left-side heavy
+ (&& and || are left-associative) and after the single parse,
+ if we are at the end of the command string, the last in a
+ series of connection commands is
+ command->value.Connection->second. */
+ else if (command->type == cm_connection && can_optimize_connection (command))
+ {
+ command->value.Connection->second->flags |= CMD_TRY_OPTIMIZING;
+ command->value.Connection->second->value.Simple->flags |= CMD_TRY_OPTIMIZING;
+ }
#endif /* ONESHOT */
/* See if this is a candidate for $( <file ). */
extern int array_expand_once;
#endif
-#if defined (SYSLOG_HISTORY) && defined (SYSLOG_SHOPT)
+#if defined (SYSLOG_HISTORY)
extern int syslog_history;
#endif
#define CMD_COPROC_SUBSHELL 0x1000
#define CMD_LASTPIPE 0x2000
#define CMD_STDPATH 0x4000 /* use standard path for command lookup */
+#define CMD_TRY_OPTIMIZING 0x8000 /* try to optimize this simple command */
/* What a command looks like. */
typedef struct command {
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
-.\" Last Change: Fri Dec 7 09:48:47 EST 2018
+.\" Last Change: Sun Jan 27 17:41:59 EST 2019
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
-.TH BASH 1 "2018 December 7" "GNU Bash 5.0"
+.TH BASH 1 "2019 January 27" "GNU Bash 5.0"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
the \fIlist\fP associated with the next set of patterns.
Using \fB;;&\fP in place of \fB;;\fP causes the shell to test the next
pattern list in the statement, if any, and execute any associated \fIlist\fP
-on a successful match.
+on a successful match,
+continuing the case statement execution as if the pattern list had not matched.
The exit status is zero if no
pattern matches. Otherwise, it is the exit status of the
last command executed in \fIlist\fP.
the @var{command-list} associated with the next clause, if any.
Using @samp{;;&} in place of @samp{;;} causes the shell to test the patterns
in the next clause, if any, and execute any associated @var{command-list}
-on a successful match.
+on a successful match,
+continuing the case statement execution as if the pattern list had not matched.
The return status is zero if no @var{pattern} is matched. Otherwise, the
return status is the exit status of the @var{command-list} executed.
@ignore
-Copyright (C) 1988-2018 Free Software Foundation, Inc.
+Copyright (C) 1988-2019 Free Software Foundation, Inc.
@end ignore
-@set LASTCHANGE Fri Dec 7 09:49:07 EST 2018
+@set LASTCHANGE Sun Jan 27 17:41:35 EST 2019
@set EDITION 5.0
@set VERSION 5.0
-@set UPDATED 7 December 2018
-@set UPDATED-MONTH December 2018
+@set UPDATED 27 January 2019
+@set UPDATED-MONTH January 2019
((command->value.Connection->connector == OR_OR) &&
(exec_result != EXECUTION_SUCCESS)))
{
+ optimize_fork (command);
+
second = command->value.Connection->second;
if (ignore_return && second)
second->flags |= CMD_IGNORE_RETURN;