((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;
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 ). */
#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 {
((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;