Bash-5.0 patch 5: prevent optimizing forks away too aggressively

This commit is contained in:
Chet Ramey 2019-04-20 14:25:52 -04:00
parent 16c907aa3b
commit 41f5420db7
4 changed files with 27 additions and 4 deletions

View File

@ -100,12 +100,22 @@ should_suppress_fork (command)
((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->connector == ';') &&
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->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') &&
(command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) &&
should_suppress_fork (command->value.Connection->second))
{
command->value.Connection->second->flags |= CMD_NO_FORK;
@ -412,8 +422,18 @@ parse_and_execute (string, from_file, flags)
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 ). */

View File

@ -186,6 +186,7 @@ typedef struct element {
#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 {

View File

@ -2767,6 +2767,8 @@ execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close)
((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;

View File

@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
#define PATCHLEVEL 4
#define PATCHLEVEL 5
#endif /* _PATCHLEVEL_H_ */