Skip to content

Commit 41f5420

Browse files
author
Chet Ramey
committed
Bash-5.0 patch 5: prevent optimizing forks away too aggressively
1 parent 16c907a commit 41f5420

File tree

4 files changed

+27
-4
lines changed

4 files changed

+27
-4
lines changed

builtins/evalstring.c

+23-3
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,22 @@ should_suppress_fork (command)
100100
((command->flags & CMD_INVERT_RETURN) == 0));
101101
}
102102

103+
int
104+
can_optimize_connection (command)
105+
COMMAND *command;
106+
{
107+
return (*bash_input.location.string == '\0' &&
108+
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') &&
109+
command->value.Connection->second->type == cm_simple);
110+
}
111+
103112
void
104113
optimize_fork (command)
105114
COMMAND *command;
106115
{
107116
if (command->type == cm_connection &&
108-
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR) &&
117+
(command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') &&
118+
(command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) &&
109119
should_suppress_fork (command->value.Connection->second))
110120
{
111121
command->value.Connection->second->flags |= CMD_NO_FORK;
@@ -412,8 +422,18 @@ parse_and_execute (string, from_file, flags)
412422
command->flags |= CMD_NO_FORK;
413423
command->value.Simple->flags |= CMD_NO_FORK;
414424
}
415-
else if (command->type == cm_connection)
416-
optimize_fork (command);
425+
426+
/* Can't optimize forks out here execept for simple commands.
427+
This knows that the parser sets up commands as left-side heavy
428+
(&& and || are left-associative) and after the single parse,
429+
if we are at the end of the command string, the last in a
430+
series of connection commands is
431+
command->value.Connection->second. */
432+
else if (command->type == cm_connection && can_optimize_connection (command))
433+
{
434+
command->value.Connection->second->flags |= CMD_TRY_OPTIMIZING;
435+
command->value.Connection->second->value.Simple->flags |= CMD_TRY_OPTIMIZING;
436+
}
417437
#endif /* ONESHOT */
418438

419439
/* See if this is a candidate for $( <file ). */

command.h

+1
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ typedef struct element {
186186
#define CMD_COPROC_SUBSHELL 0x1000
187187
#define CMD_LASTPIPE 0x2000
188188
#define CMD_STDPATH 0x4000 /* use standard path for command lookup */
189+
#define CMD_TRY_OPTIMIZING 0x8000 /* try to optimize this simple command */
189190

190191
/* What a command looks like. */
191192
typedef struct command {

execute_cmd.c

+2
Original file line numberDiff line numberDiff line change
@@ -2767,6 +2767,8 @@ execute_connection (command, asynchronous, pipe_in, pipe_out, fds_to_close)
27672767
((command->value.Connection->connector == OR_OR) &&
27682768
(exec_result != EXECUTION_SUCCESS)))
27692769
{
2770+
optimize_fork (command);
2771+
27702772
second = command->value.Connection->second;
27712773
if (ignore_return && second)
27722774
second->flags |= CMD_IGNORE_RETURN;

patchlevel.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@
2525
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
2626
looks for to find the patch level (for the sccs version string). */
2727

28-
#define PATCHLEVEL 4
28+
#define PATCHLEVEL 5
2929

3030
#endif /* _PATCHLEVEL_H_ */

0 commit comments

Comments
 (0)