diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-24 07:54:57 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-24 07:54:57 +0000 |
commit | 0b76964ae11b1d71e8634d1d7d672219dd43bde9 (patch) | |
tree | 12fa3c1e68c6b5613f8b0d279319f524d1c21a14 | |
parent | 2dc240c0d6e0b3b0b66f08ac9cc5584df824f959 (diff) | |
download | busybox-w32-0b76964ae11b1d71e8634d1d7d672219dd43bde9.tar.gz busybox-w32-0b76964ae11b1d71e8634d1d7d672219dd43bde9.tar.bz2 busybox-w32-0b76964ae11b1d71e8634d1d7d672219dd43bde9.zip |
ash: explain redirect code a bit
function old new delta
redirect 1059 1054 -5
-rw-r--r-- | shell/ash.c | 68 |
1 files changed, 39 insertions, 29 deletions
diff --git a/shell/ash.c b/shell/ash.c index 4263644fc..de1f8006d 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -594,8 +594,8 @@ struct nfile { | |||
594 | 594 | ||
595 | struct ndup { | 595 | struct ndup { |
596 | smallint type; | 596 | smallint type; |
597 | union node *next; | 597 | union node *next; /* must match nfile's layout */ |
598 | int fd; | 598 | int fd; /* must match nfile's layout */ |
599 | int dupfd; | 599 | int dupfd; |
600 | union node *vname; | 600 | union node *vname; |
601 | }; | 601 | }; |
@@ -1634,12 +1634,6 @@ nextopt(const char *optstring) | |||
1634 | * The parsefile structure pointed to by the global variable parsefile | 1634 | * The parsefile structure pointed to by the global variable parsefile |
1635 | * contains information about the current file being read. | 1635 | * contains information about the current file being read. |
1636 | */ | 1636 | */ |
1637 | struct redirtab { | ||
1638 | struct redirtab *next; | ||
1639 | int renamed[10]; | ||
1640 | int nullredirs; | ||
1641 | }; | ||
1642 | |||
1643 | struct shparam { | 1637 | struct shparam { |
1644 | int nparam; /* # of positional parameters (without $0) */ | 1638 | int nparam; /* # of positional parameters (without $0) */ |
1645 | #if ENABLE_ASH_GETOPTS | 1639 | #if ENABLE_ASH_GETOPTS |
@@ -1765,6 +1759,7 @@ static const struct { | |||
1765 | #endif | 1759 | #endif |
1766 | }; | 1760 | }; |
1767 | 1761 | ||
1762 | struct redirtab; | ||
1768 | 1763 | ||
1769 | struct globals_var { | 1764 | struct globals_var { |
1770 | struct shparam shellparam; /* $@ current positional parameters */ | 1765 | struct shparam shellparam; /* $@ current positional parameters */ |
@@ -1777,7 +1772,7 @@ struct globals_var { | |||
1777 | extern struct globals_var *const ash_ptr_to_globals_var; | 1772 | extern struct globals_var *const ash_ptr_to_globals_var; |
1778 | #define G_var (*ash_ptr_to_globals_var) | 1773 | #define G_var (*ash_ptr_to_globals_var) |
1779 | #define shellparam (G_var.shellparam ) | 1774 | #define shellparam (G_var.shellparam ) |
1780 | #define redirlist (G_var.redirlist ) | 1775 | //#define redirlist (G_var.redirlist ) |
1781 | #define g_nullredirs (G_var.g_nullredirs ) | 1776 | #define g_nullredirs (G_var.g_nullredirs ) |
1782 | #define preverrout_fd (G_var.preverrout_fd) | 1777 | #define preverrout_fd (G_var.preverrout_fd) |
1783 | #define vartab (G_var.vartab ) | 1778 | #define vartab (G_var.vartab ) |
@@ -4767,6 +4762,7 @@ openhere(union node *redir) | |||
4767 | } | 4762 | } |
4768 | } | 4763 | } |
4769 | if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { | 4764 | if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { |
4765 | /* child */ | ||
4770 | close(pip[0]); | 4766 | close(pip[0]); |
4771 | signal(SIGINT, SIG_IGN); | 4767 | signal(SIGINT, SIG_IGN); |
4772 | signal(SIGQUIT, SIG_IGN); | 4768 | signal(SIGQUIT, SIG_IGN); |
@@ -4777,7 +4773,7 @@ openhere(union node *redir) | |||
4777 | signal(SIGPIPE, SIG_DFL); | 4773 | signal(SIGPIPE, SIG_DFL); |
4778 | if (redir->type == NHERE) | 4774 | if (redir->type == NHERE) |
4779 | full_write(pip[1], redir->nhere.doc->narg.text, len); | 4775 | full_write(pip[1], redir->nhere.doc->narg.text, len); |
4780 | else | 4776 | else /* NXHERE */ |
4781 | expandhere(redir->nhere.doc, pip[1]); | 4777 | expandhere(redir->nhere.doc, pip[1]); |
4782 | _exit(EXIT_SUCCESS); | 4778 | _exit(EXIT_SUCCESS); |
4783 | } | 4779 | } |
@@ -4832,10 +4828,10 @@ openredirect(union node *redir) | |||
4832 | abort(); | 4828 | abort(); |
4833 | #endif | 4829 | #endif |
4834 | /* Fall through to eliminate warning. */ | 4830 | /* Fall through to eliminate warning. */ |
4835 | case NTOFD: | 4831 | // case NTOFD: |
4836 | case NFROMFD: | 4832 | // case NFROMFD: |
4837 | f = -1; | 4833 | // f = -1; |
4838 | break; | 4834 | // break; |
4839 | case NHERE: | 4835 | case NHERE: |
4840 | case NXHERE: | 4836 | case NXHERE: |
4841 | f = openhere(redir); | 4837 | f = openhere(redir); |
@@ -4873,19 +4869,26 @@ dupredirect(union node *redir, int f) | |||
4873 | { | 4869 | { |
4874 | int fd = redir->nfile.fd; | 4870 | int fd = redir->nfile.fd; |
4875 | 4871 | ||
4876 | if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) { | 4872 | if (f < 0) { /* redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD */ |
4877 | if (redir->ndup.dupfd >= 0) { /* if not ">&-" */ | 4873 | if (redir->ndup.dupfd >= 0) { /* if not ">&-" */ |
4878 | copyfd(redir->ndup.dupfd, fd); | 4874 | copyfd(redir->ndup.dupfd, fd); |
4879 | } | 4875 | } |
4880 | return; | 4876 | return; |
4881 | } | 4877 | } |
4882 | |||
4883 | if (f != fd) { | 4878 | if (f != fd) { |
4884 | copyfd(f, fd); | 4879 | copyfd(f, fd); |
4885 | close(f); | 4880 | close(f); |
4886 | } | 4881 | } |
4887 | } | 4882 | } |
4888 | 4883 | ||
4884 | /**/ | ||
4885 | struct redirtab { | ||
4886 | struct redirtab *next; | ||
4887 | int renamed[10]; | ||
4888 | int nullredirs; | ||
4889 | }; | ||
4890 | #define redirlist (G_var.redirlist ) | ||
4891 | |||
4889 | /* | 4892 | /* |
4890 | * Process a list of redirection commands. If the REDIR_PUSH flag is set, | 4893 | * Process a list of redirection commands. If the REDIR_PUSH flag is set, |
4891 | * old file descriptors are stashed away so that the redirection can be | 4894 | * old file descriptors are stashed away so that the redirection can be |
@@ -4921,36 +4924,43 @@ redirect(union node *redir, int flags) | |||
4921 | } | 4924 | } |
4922 | do { | 4925 | do { |
4923 | fd = redir->nfile.fd; | 4926 | fd = redir->nfile.fd; |
4924 | if ((redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) | 4927 | if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) { |
4925 | && redir->ndup.dupfd == fd) | 4928 | if (redir->ndup.dupfd == fd) |
4926 | continue; /* redirect from/to same file descriptor */ | 4929 | continue; /* redirect from/to same file descriptor */ |
4927 | 4930 | newfd = -1; | |
4928 | newfd = openredirect(redir); | 4931 | } else { |
4929 | if (fd == newfd) { | 4932 | newfd = openredirect(redir); /* always >= 0 */ |
4930 | /* Descriptor wasn't open before redirect. | 4933 | if (fd == newfd) { |
4931 | * Mark it for close in the future */ | 4934 | /* Descriptor wasn't open before redirect. |
4932 | if (sv && sv->renamed[fd] == EMPTY) | 4935 | * Mark it for close in the future */ |
4933 | sv->renamed[fd] = CLOSED; | 4936 | if (sv && sv->renamed[fd] == EMPTY) |
4934 | continue; | 4937 | sv->renamed[fd] = CLOSED; |
4938 | continue; | ||
4939 | } | ||
4935 | } | 4940 | } |
4936 | if (sv && sv->renamed[fd] == EMPTY) { | 4941 | if (sv && sv->renamed[fd] == EMPTY) { |
4942 | /* Copy old descriptor */ | ||
4937 | i = fcntl(fd, F_DUPFD, 10); | 4943 | i = fcntl(fd, F_DUPFD, 10); |
4938 | |||
4939 | if (i == -1) { | 4944 | if (i == -1) { |
4940 | i = errno; | 4945 | i = errno; |
4941 | if (i != EBADF) { | 4946 | if (i != EBADF) { /* strange error */ |
4942 | close(newfd); | 4947 | close(newfd); |
4943 | errno = i; | 4948 | errno = i; |
4944 | ash_msg_and_raise_error("%d: %m", fd); | 4949 | ash_msg_and_raise_error("%d: %m", fd); |
4945 | /* NOTREACHED */ | 4950 | /* NOTREACHED */ |
4946 | } | 4951 | } |
4952 | /* it is not open - ok */ | ||
4947 | } else { | 4953 | } else { |
4954 | /* it is open, save its copy */ | ||
4948 | sv->renamed[fd] = i; | 4955 | sv->renamed[fd] = i; |
4949 | close(fd); | 4956 | close(fd); |
4950 | } | 4957 | } |
4951 | } else { | 4958 | } else { |
4952 | close(fd); | 4959 | close(fd); |
4953 | } | 4960 | } |
4961 | /* Here fd is closed */ | ||
4962 | /* NTOFD/NFROMFD: copy redir->ndup.dupfd to fd */ | ||
4963 | /* else: move newfd to fd */ | ||
4954 | dupredirect(redir, newfd); | 4964 | dupredirect(redir, newfd); |
4955 | } while ((redir = redir->nfile.next) != NULL); | 4965 | } while ((redir = redir->nfile.next) != NULL); |
4956 | INT_ON; | 4966 | INT_ON; |