ash: remove REDIR_SAVEFD2

function                                             old     new   delta
evalcommand                                         1364    1369      +5
redirect                                            1055    1014     -41
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 5/-41)             Total: -36 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/shell/ash.c b/shell/ash.c
index 52fcc79..1e720ae 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2030,7 +2030,7 @@
 struct globals_var {
 	struct shparam shellparam;      /* $@ current positional parameters */
 	struct redirtab *redirlist;
-	int preverrout_fd;   /* save fd2 before print debug if xflag is set. */
+	int preverrout_fd;   /* stderr fd: usually 2, unless redirect moved it */
 	struct var *vartab[VTABSIZE];
 	struct var varinit[ARRAY_SIZE(varinit_data)];
 };
@@ -5426,16 +5426,13 @@
  */
 /* flags passed to redirect */
 #define REDIR_PUSH    01        /* save previous values of file descriptors */
-#define REDIR_SAVEFD2 03        /* set preverrout */
 static void
 redirect(union node *redir, int flags)
 {
 	struct redirtab *sv;
 	int sv_pos;
-	int i;
 	int fd;
 	int newfd;
-	int copied_fd2 = -1;
 
 	if (!redir)
 		return;
@@ -5479,37 +5476,38 @@
 			 * to the same fd as right side fd in N>&M */
 			int minfd = right_fd < 10 ? 10 : right_fd + 1;
 #if defined(F_DUPFD_CLOEXEC)
-			i = fcntl(fd, F_DUPFD_CLOEXEC, minfd);
+			int copy = fcntl(fd, F_DUPFD_CLOEXEC, minfd);
 #else
-			i = fcntl(fd, F_DUPFD, minfd);
+			int copy = fcntl(fd, F_DUPFD, minfd);
 #endif
-			if (i == -1) {
-				i = errno;
-				if (i != EBADF) {
+			if (copy == -1) {
+				int e = errno;
+				if (e != EBADF) {
 					/* Strange error (e.g. "too many files" EMFILE?) */
 					if (newfd >= 0)
 						close(newfd);
-					errno = i;
+					errno = e;
 					ash_msg_and_raise_perror("%d", fd);
 					/* NOTREACHED */
 				}
 				/* EBADF: it is not open - good, remember to close it */
  remember_to_close:
-				i = CLOSED;
+				copy = CLOSED;
 			} else { /* fd is open, save its copy */
 #if !defined(F_DUPFD_CLOEXEC)
-				fcntl(i, F_SETFD, FD_CLOEXEC);
+				fcntl(copy, F_SETFD, FD_CLOEXEC);
 #endif
 				/* "exec fd>&-" should not close fds
 				 * which point to script file(s).
 				 * Force them to be restored afterwards */
 				if (is_hidden_fd(sv, fd))
-					i |= COPYFD_RESTORE;
+					copy |= COPYFD_RESTORE;
 			}
-			if (fd == 2)
-				copied_fd2 = i;
+			/* if we move stderr, let "set -x" code know */
+			if (fd == preverrout_fd)
+				preverrout_fd = copy;
 			sv->two_fd[sv_pos].orig = fd;
-			sv->two_fd[sv_pos].copy = i;
+			sv->two_fd[sv_pos].copy = copy;
 			sv_pos++;
 		}
 		if (newfd < 0) {
@@ -5537,10 +5535,16 @@
 		}
 #endif
 	} while ((redir = redir->nfile.next) != NULL);
-
 	INT_ON;
-	if ((flags & REDIR_SAVEFD2) && copied_fd2 >= 0)
-		preverrout_fd = copied_fd2;
+
+//dash:#define REDIR_SAVEFD2 03        /* set preverrout */
+#define REDIR_SAVEFD2 0
+	// dash has a bug: since REDIR_SAVEFD2=3 and REDIR_PUSH=1, this test
+	// triggers for pure REDIR_PUSH too. Thus, this is done almost always,
+	// not only for calls with flags containing REDIR_SAVEFD2.
+	// We do this unconditionally (see code above).
+	//if ((flags & REDIR_SAVEFD2) && copied_fd2 >= 0)
+	//	preverrout_fd = copied_fd2;
 }
 
 static int
@@ -9655,9 +9659,7 @@
 	int spclbltin;
 	int status;
 	char **nargv;
-	struct builtincmd *bcmd;
 	smallint cmd_is_exec;
-	smallint pseudovarflag = 0;
 
 	/* First expand the arguments. */
 	TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
@@ -9674,21 +9676,24 @@
 
 	argc = 0;
 	if (cmd->ncmd.args) {
+		struct builtincmd *bcmd;
+		smallint pseudovarflag;
+
 		bcmd = find_builtin(cmd->ncmd.args->narg.text);
 		pseudovarflag = bcmd && IS_BUILTIN_ASSIGN(bcmd);
-	}
 
-	for (argp = cmd->ncmd.args; argp; argp = argp->narg.next) {
-		struct strlist **spp;
+		for (argp = cmd->ncmd.args; argp; argp = argp->narg.next) {
+			struct strlist **spp;
 
-		spp = arglist.lastp;
-		if (pseudovarflag && isassignment(argp->narg.text))
-			expandarg(argp, &arglist, EXP_VARTILDE);
-		else
-			expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
+			spp = arglist.lastp;
+			if (pseudovarflag && isassignment(argp->narg.text))
+				expandarg(argp, &arglist, EXP_VARTILDE);
+			else
+				expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
 
-		for (sp = *spp; sp; sp = sp->next)
-			argc++;
+			for (sp = *spp; sp; sp = sp->next)
+				argc++;
+		}
 	}
 
 	/* Reserve one extra spot at the front for shellexec. */
@@ -9704,9 +9709,9 @@
 	if (iflag && funcnest == 0 && argc > 0)
 		lastarg = nargv[-1];
 
-	preverrout_fd = 2;
 	expredir(cmd->ncmd.redirect);
 	redir_stop = pushredir(cmd->ncmd.redirect);
+	preverrout_fd = 2;
 	status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
 
 	path = vpath.var_text;