aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c70
1 files changed, 44 insertions, 26 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 3184249f5..e2b4eee95 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -5435,33 +5435,13 @@ redirect(union node *redir, int flags)
5435 int newfd; 5435 int newfd;
5436 int copied_fd2 = -1; 5436 int copied_fd2 = -1;
5437 5437
5438 if (!redir) { 5438 if (!redir)
5439 return; 5439 return;
5440 }
5441
5442 sv = NULL; 5440 sv = NULL;
5443 sv_pos = 0;
5444 INT_OFF; 5441 INT_OFF;
5445 if (flags & REDIR_PUSH) { 5442 if (flags & REDIR_PUSH)
5446 union node *tmp = redir; 5443 sv = redirlist;
5447 do { 5444 sv_pos = 0;
5448 sv_pos++;
5449#if BASH_REDIR_OUTPUT
5450 if (tmp->nfile.type == NTO2)
5451 sv_pos++;
5452#endif
5453 tmp = tmp->nfile.next;
5454 } while (tmp);
5455 sv = ckmalloc(sizeof(*sv) + sv_pos * sizeof(sv->two_fd[0]));
5456 sv->next = redirlist;
5457 sv->pair_count = sv_pos;
5458 redirlist = sv;
5459 while (sv_pos > 0) {
5460 sv_pos--;
5461 sv->two_fd[sv_pos].orig = sv->two_fd[sv_pos].copy = EMPTY;
5462 }
5463 }
5464
5465 do { 5445 do {
5466 int right_fd = -1; 5446 int right_fd = -1;
5467 fd = redir->nfile.fd; 5447 fd = redir->nfile.fd;
@@ -5583,6 +5563,34 @@ redirectsafe(union node *redir, int flags)
5583 return err; 5563 return err;
5584} 5564}
5585 5565
5566static struct redirtab*
5567pushredir(union node *redir)
5568{
5569 struct redirtab *sv;
5570 int i;
5571
5572 if (!redir)
5573 return redirlist;
5574
5575 i = 0;
5576 do {
5577 i++;
5578#if BASH_REDIR_OUTPUT
5579 if (redir->nfile.type == NTO2)
5580 i++;
5581#endif
5582 redir = redir->nfile.next;
5583 } while (redir);
5584
5585 sv = ckzalloc(sizeof(*sv) + i * sizeof(sv->two_fd[0]));
5586 sv->pair_count = i;
5587 while (--i >= 0)
5588 sv->two_fd[i].orig = sv->two_fd[i].copy = EMPTY;
5589 sv->next = redirlist;
5590 redirlist = sv;
5591 return sv->next;
5592}
5593
5586/* 5594/*
5587 * Undo the effects of the last redirection. 5595 * Undo the effects of the last redirection.
5588 */ 5596 */
@@ -5618,6 +5626,13 @@ popredir(int drop, int restore)
5618 INT_ON; 5626 INT_ON;
5619} 5627}
5620 5628
5629static void
5630unwindredir(struct redirtab *stop)
5631{
5632 while (redirlist != stop)
5633 popredir(/*drop:*/ 0, /*restore:*/ 0);
5634}
5635
5621 5636
5622/* ============ Routines to expand arguments to commands 5637/* ============ Routines to expand arguments to commands
5623 * 5638 *
@@ -8727,6 +8742,7 @@ evaltree(union node *n, int flags)
8727 goto setstatus; 8742 goto setstatus;
8728 case NREDIR: 8743 case NREDIR:
8729 expredir(n->nredir.redirect); 8744 expredir(n->nredir.redirect);
8745 pushredir(n->nredir.redirect);
8730 status = redirectsafe(n->nredir.redirect, REDIR_PUSH); 8746 status = redirectsafe(n->nredir.redirect, REDIR_PUSH);
8731 if (!status) { 8747 if (!status) {
8732 status = evaltree(n->nredir.n, flags & EV_TESTED); 8748 status = evaltree(n->nredir.n, flags & EV_TESTED);
@@ -9622,6 +9638,7 @@ evalcommand(union node *cmd, int flags)
9622 "\0\0", bltincmd /* why three NULs? */ 9638 "\0\0", bltincmd /* why three NULs? */
9623 }; 9639 };
9624 struct localvar_list *localvar_stop; 9640 struct localvar_list *localvar_stop;
9641 struct redirtab *redir_stop;
9625 struct stackmark smark; 9642 struct stackmark smark;
9626 union node *argp; 9643 union node *argp;
9627 struct arglist arglist; 9644 struct arglist arglist;
@@ -9687,6 +9704,7 @@ evalcommand(union node *cmd, int flags)
9687 9704
9688 preverrout_fd = 2; 9705 preverrout_fd = 2;
9689 expredir(cmd->ncmd.redirect); 9706 expredir(cmd->ncmd.redirect);
9707 redir_stop = pushredir(cmd->ncmd.redirect);
9690 status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2); 9708 status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
9691 9709
9692 path = vpath.var_text; 9710 path = vpath.var_text;
@@ -9878,6 +9896,7 @@ evalcommand(union node *cmd, int flags)
9878 out: 9896 out:
9879 if (cmd->ncmd.redirect) 9897 if (cmd->ncmd.redirect)
9880 popredir(/*drop:*/ cmd_is_exec, /*restore:*/ cmd_is_exec); 9898 popredir(/*drop:*/ cmd_is_exec, /*restore:*/ cmd_is_exec);
9899 unwindredir(redir_stop);
9881 unwindlocalvars(localvar_stop); 9900 unwindlocalvars(localvar_stop);
9882 if (lastarg) { 9901 if (lastarg) {
9883 /* dsl: I think this is intended to be used to support 9902 /* dsl: I think this is intended to be used to support
@@ -13584,8 +13603,7 @@ reset(void)
13584 popallfiles(); 13603 popallfiles();
13585 13604
13586 /* from redir.c: */ 13605 /* from redir.c: */
13587 while (redirlist) 13606 unwindredir(NULL);
13588 popredir(/*drop:*/ 0, /*restore:*/ 0);
13589 13607
13590 /* from var.c: */ 13608 /* from var.c: */
13591 unwindlocalvars(NULL); 13609 unwindlocalvars(NULL);