aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-24 07:54:57 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-24 07:54:57 +0000
commit0b76964ae11b1d71e8634d1d7d672219dd43bde9 (patch)
tree12fa3c1e68c6b5613f8b0d279319f524d1c21a14
parent2dc240c0d6e0b3b0b66f08ac9cc5584df824f959 (diff)
downloadbusybox-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.c68
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
595struct ndup { 595struct 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 */
1637struct redirtab {
1638 struct redirtab *next;
1639 int renamed[10];
1640 int nullredirs;
1641};
1642
1643struct shparam { 1637struct 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
1762struct redirtab;
1768 1763
1769struct globals_var { 1764struct globals_var {
1770 struct shparam shellparam; /* $@ current positional parameters */ 1765 struct shparam shellparam; /* $@ current positional parameters */
@@ -1777,7 +1772,7 @@ struct globals_var {
1777extern struct globals_var *const ash_ptr_to_globals_var; 1772extern 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/**/
4885struct 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;