diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-02-11 18:10:06 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-02-11 18:10:06 +0000 |
commit | a5f2cd30c9308b3cec359acdf79d60958d6d5834 (patch) | |
tree | ec87507a5ef3b8b3d4884d426ad9e33d3b2b440a /shell | |
parent | fc213058921209263b94a1e1a000718f2d61ebee (diff) | |
download | busybox-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.c | 83 |
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) | |||
2689 | static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp) | 2688 | static 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) ℘ | 2712 | (void) ℘ |
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 | |||
4633 | static void pushio(struct ioarg *argp, int (*fn) (struct ioarg *)) | 4632 | static 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) | |||
4967 | static void closepipe(int *pv) | 4966 | static 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 | ||