hush: make pun_pipe loop clearer; fix "cmd | var=`cmd` | cmd" handling
function old new delta
free_strings - 38 +38
pseudo_exec_argv 161 171 +10
free_pipe 227 205 -22
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/1 up/down: 48/-22) Total: 26 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/shell/hush.c b/shell/hush.c
index 31ca22a..8a467be 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -3713,11 +3713,17 @@
{
char **new_env;
- /* Case when we are here: ... | var=val | ... */
- if (!argv[assignment_cnt])
- _exit(EXIT_SUCCESS);
-
new_env = expand_assignments(argv, assignment_cnt);
+
+ if (!argv[assignment_cnt]) {
+ /* Case when we are here: ... | var=val | ...
+ * (note that we do not exit early, i.e., do not optimize out
+ * expand_assignments(): think about ... | var=`sleep 1` | ...
+ */
+ free_strings(new_env);
+ _exit(EXIT_SUCCESS);
+ }
+
#if BB_MMU
set_vars_and_save_old(new_env);
free(new_env); /* optional */
@@ -3727,6 +3733,7 @@
nommu_save->new_env = new_env;
nommu_save->old_vars = set_vars_and_save_old(new_env);
#endif
+
if (argv_expanded) {
argv = argv_expanded;
} else {
@@ -4145,8 +4152,9 @@
static NOINLINE int run_pipe(struct pipe *pi)
{
static const char *const null_ptr = NULL;
- int i;
- int nextin;
+
+ int cmd_no;
+ int next_infd;
struct command *command;
char **argv_expanded;
char **argv;
@@ -4160,7 +4168,7 @@
IF_HUSH_JOB(pi->pgrp = -1;)
pi->stopped_cmds = 0;
- command = &(pi->cmds[0]);
+ command = &pi->cmds[0];
argv_expanded = NULL;
if (pi->num_cmds != 1
@@ -4358,9 +4366,10 @@
/* Going to fork a child per each pipe member */
pi->alive_cmds = 0;
- nextin = 0;
+ next_infd = 0;
- for (i = 0; i < pi->num_cmds; i++) {
+ cmd_no = 0;
+ while (cmd_no < pi->num_cmds) {
struct fd_pair pipefds;
#if !BB_MMU
volatile nommu_save_t nommu_save;
@@ -4369,7 +4378,8 @@
nommu_save.argv = NULL;
nommu_save.argv_from_re_execing = NULL;
#endif
- command = &(pi->cmds[i]);
+ command = &pi->cmds[cmd_no];
+ cmd_no++;
if (command->argv) {
debug_printf_exec(": pipe member '%s' '%s'...\n",
command->argv[0], command->argv[1]);
@@ -4380,7 +4390,7 @@
/* pipes are inserted between pairs of commands */
pipefds.rd = 0;
pipefds.wr = 1;
- if ((i + 1) < pi->num_cmds)
+ if (cmd_no < pi->num_cmds)
xpiped_pair(pipefds);
command->pid = BB_MMU ? fork() : vfork();
@@ -4413,7 +4423,7 @@
if (open(bb_dev_null, O_RDONLY))
xopen("/", O_RDONLY);
} else {
- xmove_fd(nextin, 0);
+ xmove_fd(next_infd, 0);
}
xmove_fd(pipefds.wr, 1);
if (pipefds.rd > 1)
@@ -4460,12 +4470,12 @@
#endif
}
- if (i)
- close(nextin);
- if ((i + 1) < pi->num_cmds)
+ if (cmd_no > 1)
+ close(next_infd);
+ if (cmd_no < pi->num_cmds)
close(pipefds.wr);
/* Pass read (output) pipe end to next iteration */
- nextin = pipefds.rd;
+ next_infd = pipefds.rd;
}
if (!pi->alive_cmds) {
@@ -7153,7 +7163,7 @@
#endif
case 'n':
case 'x':
- if (!set_mode('-', opt))
+ if (set_mode('-', opt) == 0) /* no error */
break;
default:
#ifndef BB_VER