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 | ||
