diff options
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 70 |
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 | ||
5566 | static struct redirtab* | ||
5567 | pushredir(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 | ||
5629 | static void | ||
5630 | unwindredir(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); |