aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-02-11 18:10:06 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-02-11 18:10:06 +0000
commita5f2cd30c9308b3cec359acdf79d60958d6d5834 (patch)
treeec87507a5ef3b8b3d4884d426ad9e33d3b2b440a /shell
parentfc213058921209263b94a1e1a000718f2d61ebee (diff)
downloadbusybox-w32-a5f2cd30c9308b3cec359acdf79d60958d6d5834.tar.gz
busybox-w32-a5f2cd30c9308b3cec359acdf79d60958d6d5834.tar.bz2
busybox-w32-a5f2cd30c9308b3cec359acdf79d60958d6d5834.zip
msh: do not run pipes where last command is a builtin
msh: code shrink and some renames for better readability
Diffstat (limited to 'shell')
-rw-r--r--shell/msh.c83
1 files changed, 41 insertions, 42 deletions
diff --git a/shell/msh.c b/shell/msh.c
index 531ae779a..f05028f26 100644
--- a/shell/msh.c
+++ b/shell/msh.c
@@ -2553,8 +2553,7 @@ static int execute(struct op *t, int *pin, int *pout, int act)
2553 interactive = hinteractive; 2553 interactive = hinteractive;
2554 if (i != -1) { 2554 if (i != -1) {
2555 setval(lookup("!"), putn(i)); 2555 setval(lookup("!"), putn(i));
2556 if (pin != NULL) 2556 closepipe(pin);
2557 closepipe(pin);
2558 if (interactive) { 2557 if (interactive) {
2559 prs(putn(i)); 2558 prs(putn(i));
2560 prs("\n"); 2559 prs("\n");
@@ -2689,8 +2688,8 @@ static builtin_func_ptr inbuilt(const char *s)
2689static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp) 2688static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2690{ 2689{
2691 pid_t newpid; 2690 pid_t newpid;
2692 int i, rv; 2691 int i;
2693 builtin_func_ptr shcom = NULL; 2692 builtin_func_ptr bltin = NULL;
2694 int f; 2693 int f;
2695 const char *cp = NULL; 2694 const char *cp = NULL;
2696 struct ioword **iopp; 2695 struct ioword **iopp;
@@ -2711,7 +2710,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2711 (void) &pin; 2710 (void) &pin;
2712 (void) &pout; 2711 (void) &pout;
2713 (void) &wp; 2712 (void) &wp;
2714 (void) &shcom; 2713 (void) &bltin;
2715 (void) &cp; 2714 (void) &cp;
2716 (void) &resetsig; 2715 (void) &resetsig;
2717 (void) &owp; 2716 (void) &owp;
@@ -2724,7 +2723,6 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2724 2723
2725 owp = wp; 2724 owp = wp;
2726 resetsig = 0; 2725 resetsig = 0;
2727 rv = -1; /* system-detected error */
2728 if (t->type == TCOM) { 2726 if (t->type == TCOM) {
2729 while (*wp++ != NULL) 2727 while (*wp++ != NULL)
2730 continue; 2728 continue;
@@ -2745,17 +2743,17 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2745 return setstatus(0); 2743 return setstatus(0);
2746 } 2744 }
2747 if (cp != NULL) { 2745 if (cp != NULL) {
2748 shcom = inbuilt(cp); 2746 bltin = inbuilt(cp);
2749 } 2747 }
2750 } 2748 }
2751 2749
2752 t->words = wp; 2750 t->words = wp;
2753 f = act; 2751 f = act;
2754 2752
2755 DBGPRINTF(("FORKEXEC: shcom %p, f&FEXEC 0x%x, owp %p\n", shcom, 2753 DBGPRINTF(("FORKEXEC: bltin %p, f&FEXEC 0x%x, owp %p\n", bltin,
2756 f & FEXEC, owp)); 2754 f & FEXEC, owp));
2757 2755
2758 if (shcom == NULL && (f & FEXEC) == 0) { 2756 if (!bltin && (f & FEXEC) == 0) {
2759 /* Save values in case the child process alters them */ 2757 /* Save values in case the child process alters them */
2760 hpin = pin; 2758 hpin = pin;
2761 hpout = pout; 2759 hpout = pout;
@@ -2783,18 +2781,13 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2783 intr = hintr; 2781 intr = hintr;
2784 brklist = hbrklist; 2782 brklist = hbrklist;
2785 execflg = hexecflg; 2783 execflg = hexecflg;
2786/* moved up
2787 if (i == -1)
2788 return rv;
2789*/
2790 if (pin != NULL)
2791 closepipe(pin);
2792 2784
2785 closepipe(pin);
2793 return (pout == NULL ? setstatus(waitfor(newpid, 0)) : 0); 2786 return (pout == NULL ? setstatus(waitfor(newpid, 0)) : 0);
2794 } 2787 }
2795 2788
2796 /* Must be the child process, pid should be 0 */ 2789 /* Child */
2797 DBGPRINTF(("FORKEXEC: child process, shcom=%p\n", shcom)); 2790 DBGPRINTF(("FORKEXEC: child process, bltin=%p\n", bltin));
2798 2791
2799 if (interactive) { 2792 if (interactive) {
2800 signal(SIGINT, SIG_IGN); 2793 signal(SIGINT, SIG_IGN);
@@ -2808,13 +2801,18 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2808 execflg = 0; 2801 execflg = 0;
2809 } 2802 }
2810 2803
2811 if (owp != NULL) 2804 if (owp)
2812 while ((cp = *owp++) != NULL && assign(cp, COPYV)) 2805 while ((cp = *owp++) != NULL && assign(cp, COPYV))
2813 if (shcom == NULL) 2806 if (!bltin)
2814 export(lookup(cp)); 2807 export(lookup(cp));
2815 2808
2816#ifdef COMPIPE 2809#if 1
2817 if ((pin != NULL || pout != NULL) && shcom != NULL && shcom != doexec) { 2810 /* How to fix it:
2811 * explicitly pass pin[0] and pout[1] to builtins
2812 * instead of making them rely on fd 0/1,
2813 * and do not xmove_fd(pin[0]/pout[1]) below if bltin != NULL.
2814 */
2815 if ((pin || pout) && bltin && bltin != doexec) {
2818 err("piping to/from shell builtins not yet done"); 2816 err("piping to/from shell builtins not yet done");
2819 if (forked) 2817 if (forked)
2820 _exit(-1); 2818 _exit(-1);
@@ -2822,20 +2820,20 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2822 } 2820 }
2823#endif 2821#endif
2824 2822
2825 if (pin != NULL) { 2823 if (pin) {
2826 xmove_fd(pin[0], 0); 2824 xmove_fd(pin[0], 0);
2827 if (pin[1] != 0) 2825 if (pin[1] != 0)
2828 close(pin[1]); 2826 close(pin[1]);
2829 } 2827 }
2830 if (pout != NULL) { 2828 if (pout) {
2831 xmove_fd(pout[1], 1); 2829 xmove_fd(pout[1], 1);
2832 if (pout[1] != 1) 2830 if (pout[0] > 1)
2833 close(pout[0]); 2831 close(pout[0]);
2834 } 2832 }
2835 2833
2836 iopp = t->ioact; 2834 iopp = t->ioact;
2837 if (iopp != NULL) { 2835 if (iopp) {
2838 if (shcom != NULL && shcom != doexec) { 2836 if (bltin && bltin != doexec) {
2839 prs(cp); 2837 prs(cp);
2840 err(": cannot redirect shell command"); 2838 err(": cannot redirect shell command");
2841 if (forked) 2839 if (forked)
@@ -2844,17 +2842,25 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2844 } 2842 }
2845 while (*iopp) 2843 while (*iopp)
2846 if (iosetup(*iopp++, pin != NULL, pout != NULL)) { 2844 if (iosetup(*iopp++, pin != NULL, pout != NULL)) {
2845 /* system-detected error */
2847 if (forked) 2846 if (forked)
2848 _exit(rv); 2847 _exit(-1);
2849 return rv; 2848 return -1;
2850 } 2849 }
2851 } 2850 }
2852 2851
2853 if (shcom) { 2852 if (bltin) {
2854 i = setstatus((*shcom) (t)); 2853 i = setstatus(bltin(t));
2855 if (forked) 2854 if (forked)
2856 _exit(i); 2855 _exit(i);
2857 DBGPRINTF(("FORKEXEC: returning i=%d\n", i)); 2856 DBGPRINTF(("FORKEXEC: returning i=%d\n", i));
2857/* Builtins in pipes ("ls /dev/null | cd"):
2858 * here "cd" (which is not a child) will return to main msh,
2859 * and we will read from ls's output as if it is our next command!
2860 * Result: "/dev/null: cannot execute"
2861 * and then we reach EOF on stdin and exit.
2862 * See above for possible way to fix this.
2863 */
2858 return i; 2864 return i;
2859 } 2865 }
2860 2866
@@ -2882,7 +2888,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2882 2888
2883 leave(); 2889 leave();
2884 /* NOTREACHED */ 2890 /* NOTREACHED */
2885 _exit(1); 2891 return 0;
2886} 2892}
2887 2893
2888/* 2894/*
@@ -3056,7 +3062,7 @@ static const char *rexecve(char *c, char **v, char **envp)
3056 int i; 3062 int i;
3057 const char *sp; 3063 const char *sp;
3058 char *tp; 3064 char *tp;
3059 int eacces = 0, asis = 0; 3065 int asis = 0;
3060 char *name = c; 3066 char *name = c;
3061 3067
3062 if (ENABLE_FEATURE_SH_STANDALONE) { 3068 if (ENABLE_FEATURE_SH_STANDALONE) {
@@ -3104,10 +3110,6 @@ static const char *rexecve(char *c, char **v, char **envp)
3104 3110
3105 case E2BIG: 3111 case E2BIG:
3106 return "argument list too long"; 3112 return "argument list too long";
3107
3108 case EACCES:
3109 eacces++;
3110 break;
3111 } 3113 }
3112 } 3114 }
3113 return errno == ENOENT ? "not found" : "cannot execute"; 3115 return errno == ENOENT ? "not found" : "cannot execute";
@@ -3280,8 +3282,7 @@ static int doumask(struct op *t)
3280 fputc('0' + ((i >> n) & 07), stderr); 3282 fputc('0' + ((i >> n) & 07), stderr);
3281 fputc('\n', stderr); 3283 fputc('\n', stderr);
3282 } else { 3284 } else {
3283/* huh??? '8','9' are not allowed! */ 3285 for (n = 0; *cp >= '0' && *cp <= '7'; cp++)
3284 for (n = 0; *cp >= '0' && *cp <= '9'; cp++)
3285 n = n * 8 + (*cp - '0'); 3286 n = n * 8 + (*cp - '0');
3286 umask(n); 3287 umask(n);
3287 } 3288 }
@@ -4618,7 +4619,6 @@ static int readc(void)
4618 4619
4619 DBGPRINTF(("READC: leave()...\n")); 4620 DBGPRINTF(("READC: leave()...\n"));
4620 leave(); 4621 leave();
4621
4622 /* NOTREACHED */ 4622 /* NOTREACHED */
4623 return 0; 4623 return 0;
4624} 4624}
@@ -4629,7 +4629,6 @@ static void ioecho(char c)
4629 write(2, &c, sizeof c); 4629 write(2, &c, sizeof c);
4630} 4630}
4631 4631
4632
4633static void pushio(struct ioarg *argp, int (*fn) (struct ioarg *)) 4632static void pushio(struct ioarg *argp, int (*fn) (struct ioarg *))
4634{ 4633{
4635 DBGPRINTF(("PUSHIO: argp %p, argp->afid 0x%x, global_env.iop %p\n", argp, 4634 DBGPRINTF(("PUSHIO: argp %p, argp->afid 0x%x, global_env.iop %p\n", argp,
@@ -4967,8 +4966,8 @@ static int openpipe(int *pv)
4967static void closepipe(int *pv) 4966static void closepipe(int *pv)
4968{ 4967{
4969 if (pv != NULL) { 4968 if (pv != NULL) {
4970 close(*pv++); 4969 close(pv[0]);
4971 close(*pv); 4970 close(pv[1]);
4972 } 4971 }
4973} 4972}
4974 4973