aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-02-12 09:51:03 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-02-12 09:51:03 +0000
commit7e497527ea2edf0d75c9de243ba8202eaf87ee9d (patch)
treef08b32894dd919f2b4f7652c40a36d65282b9bc1
parente26b2783a5d8e69d14e5531244c4f2c93312e715 (diff)
downloadbusybox-w32-7e497527ea2edf0d75c9de243ba8202eaf87ee9d.tar.gz
busybox-w32-7e497527ea2edf0d75c9de243ba8202eaf87ee9d.tar.bz2
busybox-w32-7e497527ea2edf0d75c9de243ba8202eaf87ee9d.zip
msh: instead of fixing "ls | cd", "cd | ls" etc just disallow
builtins in pipes. They make no sense there anyway. msh: shrink umask builtin. function old new delta execute 2508 2509 +1 doset 326 317 -9 forkexec 1370 1345 -25 doumask 165 101 -64 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/3 up/down: 1/-98) Total: -97 bytes
-rw-r--r--shell/msh.c180
1 files changed, 85 insertions, 95 deletions
diff --git a/shell/msh.c b/shell/msh.c
index 99b03947e..ee54ef2d4 100644
--- a/shell/msh.c
+++ b/shell/msh.c
@@ -86,7 +86,7 @@ static char *itoa(int n)
86# include "busybox.h" /* for applet_names */ 86# include "busybox.h" /* for applet_names */
87#endif 87#endif
88 88
89/*#define MSHDEBUG 1*/ 89//#define MSHDEBUG 4
90 90
91#ifdef MSHDEBUG 91#ifdef MSHDEBUG
92int mshdbg = MSHDEBUG; 92int mshdbg = MSHDEBUG;
@@ -244,11 +244,6 @@ static const char *const T_CMD_NAMES[] = {
244}; 244};
245#endif 245#endif
246 246
247/*
248 * actions determining the environment of a process
249 */
250#define FEXEC 1 /* execute without forking */
251
252#define AREASIZE (90000) 247#define AREASIZE (90000)
253 248
254/* 249/*
@@ -402,8 +397,6 @@ struct var {
402 397
403static int yyparse(void); 398static int yyparse(void);
404 399
405static int execute(struct op *t, int *pin, int *pout, int act);
406
407 400
408/* -------- io.h -------- */ 401/* -------- io.h -------- */
409/* io buffer */ 402/* io buffer */
@@ -495,7 +488,8 @@ static char **getwords(struct wdblock *wb);
495 488
496/* -------- misc stuff -------- */ 489/* -------- misc stuff -------- */
497 490
498static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp); 491static int forkexec(struct op *t, int *pin, int *pout, int no_fork, char **wp);
492static int execute(struct op *t, int *pin, int *pout, int no_fork);
499static int iosetup(struct ioword *iop, int pipein, int pipeout); 493static int iosetup(struct ioword *iop, int pipein, int pipeout);
500static void brkset(struct brkcon *bc); 494static void brkset(struct brkcon *bc);
501static int dolabel(struct op *t); 495static int dolabel(struct op *t);
@@ -564,10 +558,13 @@ static const char *const signame[] = {
564}; 558};
565 559
566 560
561typedef int (*builtin_func_ptr)(struct op *);
562
567struct builtincmd { 563struct builtincmd {
568 const char *name; 564 const char *name;
569 int (*builtinfunc)(struct op *t); 565 builtin_func_ptr builtinfunc;
570}; 566};
567
571static const struct builtincmd builtincmds[] = { 568static const struct builtincmd builtincmds[] = {
572 { "." , dodot }, 569 { "." , dodot },
573 { ":" , dolabel }, 570 { ":" , dolabel },
@@ -1373,7 +1370,7 @@ static void onecommand(void)
1373 if (!FLAG['n']) { 1370 if (!FLAG['n']) {
1374 DBGPRINTF(("ONECOMMAND: calling execute, t=outtree=%p\n", 1371 DBGPRINTF(("ONECOMMAND: calling execute, t=outtree=%p\n",
1375 outtree)); 1372 outtree));
1376 execute(outtree, NOPIPE, NOPIPE, 0); 1373 execute(outtree, NOPIPE, NOPIPE, /* no_fork: */ 0);
1377 } 1374 }
1378 1375
1379 if (!interactive && intr) { 1376 if (!interactive && intr) {
@@ -2450,7 +2447,7 @@ static struct op *findcase(struct op *t, const char *w)
2450 * execute tree 2447 * execute tree
2451 */ 2448 */
2452 2449
2453static int execute(struct op *t, int *pin, int *pout, int act) 2450static int execute(struct op *t, int *pin, int *pout, int no_fork)
2454{ 2451{
2455 struct op *t1; 2452 struct op *t1;
2456 volatile int i, rv, a; 2453 volatile int i, rv, a;
@@ -2495,17 +2492,17 @@ static int execute(struct op *t, int *pin, int *pout, int act)
2495 outtree = outtree_save; 2492 outtree = outtree_save;
2496 2493
2497 if (t->left) 2494 if (t->left)
2498 rv = execute(t->left, pin, pout, 0); 2495 rv = execute(t->left, pin, pout, /* no_fork: */ 0);
2499 if (t->right) 2496 if (t->right)
2500 rv = execute(t->right, pin, pout, 0); 2497 rv = execute(t->right, pin, pout, /* no_fork: */ 0);
2501 break; 2498 break;
2502 2499
2503 case TPAREN: 2500 case TPAREN:
2504 rv = execute(t->left, pin, pout, 0); 2501 rv = execute(t->left, pin, pout, /* no_fork: */ 0);
2505 break; 2502 break;
2506 2503
2507 case TCOM: 2504 case TCOM:
2508 rv = forkexec(t, pin, pout, act, wp); 2505 rv = forkexec(t, pin, pout, no_fork, wp);
2509 break; 2506 break;
2510 2507
2511 case TPIPE: 2508 case TPIPE:
@@ -2517,14 +2514,14 @@ static int execute(struct op *t, int *pin, int *pout, int act)
2517 break; 2514 break;
2518 pv[0] = remap(pv[0]); 2515 pv[0] = remap(pv[0]);
2519 pv[1] = remap(pv[1]); 2516 pv[1] = remap(pv[1]);
2520 (void) execute(t->left, pin, pv, 0); 2517 (void) execute(t->left, pin, pv, /* no_fork: */ 0);
2521 rv = execute(t->right, pv, pout, 0); 2518 rv = execute(t->right, pv, pout, /* no_fork: */ 0);
2522 } 2519 }
2523 break; 2520 break;
2524 2521
2525 case TLIST: 2522 case TLIST:
2526 (void) execute(t->left, pin, pout, 0); 2523 (void) execute(t->left, pin, pout, /* no_fork: */ 0);
2527 rv = execute(t->right, pin, pout, 0); 2524 rv = execute(t->right, pin, pout, /* no_fork: */ 0);
2528 break; 2525 break;
2529 2526
2530 case TASYNC: 2527 case TASYNC:
@@ -2544,7 +2541,7 @@ static int execute(struct op *t, int *pin, int *pout, int act)
2544 close(0); 2541 close(0);
2545 xopen(bb_dev_null, O_RDONLY); 2542 xopen(bb_dev_null, O_RDONLY);
2546 } 2543 }
2547 _exit(execute(t->left, pin, pout, FEXEC)); 2544 _exit(execute(t->left, pin, pout, /* no_fork: */ 1));
2548 } 2545 }
2549 interactive = hinteractive; 2546 interactive = hinteractive;
2550 if (i != -1) { 2547 if (i != -1) {
@@ -2562,10 +2559,10 @@ static int execute(struct op *t, int *pin, int *pout, int act)
2562 2559
2563 case TOR: 2560 case TOR:
2564 case TAND: 2561 case TAND:
2565 rv = execute(t->left, pin, pout, 0); 2562 rv = execute(t->left, pin, pout, /* no_fork: */ 0);
2566 t1 = t->right; 2563 t1 = t->right;
2567 if (t1 != NULL && (rv == 0) == (t->type == TAND)) 2564 if (t1 != NULL && (rv == 0) == (t->type == TAND))
2568 rv = execute(t1, pin, pout, 0); 2565 rv = execute(t1, pin, pout, /* no_fork: */ 0);
2569 break; 2566 break;
2570 2567
2571 case TFOR: 2568 case TFOR:
@@ -2585,7 +2582,7 @@ static int execute(struct op *t, int *pin, int *pout, int act)
2585 brkset(&bc); 2582 brkset(&bc);
2586 for (t1 = t->left; i-- && *wp != NULL;) { 2583 for (t1 = t->left; i-- && *wp != NULL;) {
2587 setval(vp, *wp++); 2584 setval(vp, *wp++);
2588 rv = execute(t1, pin, pout, 0); 2585 rv = execute(t1, pin, pout, /* no_fork: */ 0);
2589 } 2586 }
2590 brklist = brklist->nextlev; 2587 brklist = brklist->nextlev;
2591 break; 2588 break;
@@ -2597,17 +2594,17 @@ static int execute(struct op *t, int *pin, int *pout, int act)
2597 goto broken; 2594 goto broken;
2598 brkset(&bc); 2595 brkset(&bc);
2599 t1 = t->left; 2596 t1 = t->left;
2600 while ((execute(t1, pin, pout, 0) == 0) == (t->type == TWHILE)) 2597 while ((execute(t1, pin, pout, /* no_fork: */ 0) == 0) == (t->type == TWHILE))
2601 rv = execute(t->right, pin, pout, 0); 2598 rv = execute(t->right, pin, pout, /* no_fork: */ 0);
2602 brklist = brklist->nextlev; 2599 brklist = brklist->nextlev;
2603 break; 2600 break;
2604 2601
2605 case TIF: 2602 case TIF:
2606 case TELIF: 2603 case TELIF:
2607 if (t->right != NULL) { 2604 if (t->right != NULL) {
2608 rv = !execute(t->left, pin, pout, 0) ? 2605 rv = !execute(t->left, pin, pout, /* no_fork: */ 0) ?
2609 execute(t->right->left, pin, pout, 0) : 2606 execute(t->right->left, pin, pout, /* no_fork: */ 0) :
2610 execute(t->right->right, pin, pout, 0); 2607 execute(t->right->right, pin, pout, /* no_fork: */ 0);
2611 } 2608 }
2612 break; 2609 break;
2613 2610
@@ -2623,7 +2620,7 @@ static int execute(struct op *t, int *pin, int *pout, int act)
2623 t1 = findcase(t->left, cp); 2620 t1 = findcase(t->left, cp);
2624 if (t1 != NULL) { 2621 if (t1 != NULL) {
2625 DBGPRINTF7(("EXECUTE: TCASE, calling execute(t=%p, t1=%p)...\n", t, t1)); 2622 DBGPRINTF7(("EXECUTE: TCASE, calling execute(t=%p, t1=%p)...\n", t, t1));
2626 rv = execute(t1, pin, pout, 0); 2623 rv = execute(t1, pin, pout, /* no_fork: */ 0);
2627 DBGPRINTF7(("EXECUTE: TCASE, back from execute(t=%p, t1=%p)...\n", t, t1)); 2624 DBGPRINTF7(("EXECUTE: TCASE, back from execute(t=%p, t1=%p)...\n", t, t1));
2628 } 2625 }
2629 break; 2626 break;
@@ -2641,7 +2638,7 @@ static int execute(struct op *t, int *pin, int *pout, int act)
2641 if (rv >= 0) { 2638 if (rv >= 0) {
2642 t1 = t->left; 2639 t1 = t->left;
2643 if (t1) { 2640 if (t1) {
2644 rv = execute(t1, pin, pout, 0); 2641 rv = execute(t1, pin, pout, /* no_fork: */ 0);
2645 } 2642 }
2646 } 2643 }
2647 break; 2644 break;
@@ -2669,8 +2666,6 @@ static int execute(struct op *t, int *pin, int *pout, int act)
2669 return rv; 2666 return rv;
2670} 2667}
2671 2668
2672typedef int (*builtin_func_ptr)(struct op *);
2673
2674static builtin_func_ptr inbuilt(const char *s) 2669static builtin_func_ptr inbuilt(const char *s)
2675{ 2670{
2676 const struct builtincmd *bp; 2671 const struct builtincmd *bp;
@@ -2681,17 +2676,17 @@ static builtin_func_ptr inbuilt(const char *s)
2681 return NULL; 2676 return NULL;
2682} 2677}
2683 2678
2684static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp) 2679static int forkexec(struct op *t, int *pin, int *pout, int no_fork, char **wp)
2685{ 2680{
2686 pid_t newpid; 2681 pid_t newpid;
2687 int i; 2682 int i;
2688 builtin_func_ptr bltin = NULL; 2683 builtin_func_ptr bltin = NULL;
2689 int f; 2684 const char *bltin_name = NULL;
2690 const char *cp = NULL; 2685 const char *cp;
2691 struct ioword **iopp; 2686 struct ioword **iopp;
2692 int resetsig; 2687 int resetsig;
2693 char **owp; 2688 char **owp;
2694 int forked = 0; 2689 int forked;
2695 2690
2696 int *hpin = pin; 2691 int *hpin = pin;
2697 int *hpout = pout; 2692 int *hpout = pout;
@@ -2712,11 +2707,10 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2712 (void) &owp; 2707 (void) &owp;
2713#endif 2708#endif
2714 2709
2715 DBGPRINTF(("FORKEXEC: t=%p, pin %p, pout %p, act %d\n", t, pin, 2710 DBGPRINTF(("FORKEXEC: t=%p, pin %p, pout %p, no_fork %d\n", t, pin,
2716 pout, act)); 2711 pout, no_fork));
2717 DBGPRINTF7(("FORKEXEC: t->words is %s\n", 2712 DBGPRINTF7(("FORKEXEC: t->words is %s\n",
2718 ((t->words == NULL) ? "NULL" : t->words[0]))); 2713 ((t->words == NULL) ? "NULL" : t->words[0])));
2719
2720 owp = wp; 2714 owp = wp;
2721 resetsig = 0; 2715 resetsig = 0;
2722 if (t->type == TCOM) { 2716 if (t->type == TCOM) {
@@ -2725,32 +2719,36 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2725 cp = *wp; 2719 cp = *wp;
2726 2720
2727 /* strip all initial assignments */ 2721 /* strip all initial assignments */
2728 /* not correct wrt PATH=yyy command etc */ 2722 /* FIXME: not correct wrt PATH=yyy command etc */
2729 if (FLAG['x']) { 2723 if (FLAG['x']) {
2730 DBGPRINTF9(("FORKEXEC: echo'ing, cp=%p, wp=%p, owp=%p\n", 2724 DBGPRINTF9(("FORKEXEC: echo'ing, cp=%p, wp=%p, owp=%p\n",
2731 cp, wp, owp)); 2725 cp, wp, owp));
2732 echo(cp ? wp : owp); 2726 echo(cp ? wp : owp);
2733 } 2727 }
2734 2728
2735 if (cp == NULL && t->ioact == NULL) { 2729 if (cp == NULL) {
2736 while ((cp = *owp++) != NULL && assign(cp, COPYV)) 2730 if (t->ioact == NULL) {
2737 continue; 2731 while ((cp = *owp++) != NULL && assign(cp, COPYV))
2738 DBGPRINTF(("FORKEXEC: returning setstatus()\n")); 2732 continue;
2739 return setstatus(0); 2733 DBGPRINTF(("FORKEXEC: returning setstatus(0)\n"));
2740 } 2734 return setstatus(0);
2741 if (cp != NULL) { 2735 }
2736 } else { /* cp != NULL */
2737 bltin_name = cp;
2742 bltin = inbuilt(cp); 2738 bltin = inbuilt(cp);
2743 } 2739 }
2744 } 2740 }
2745 2741
2742 forked = 0;
2746 t->words = wp; 2743 t->words = wp;
2747 f = act; 2744 DBGPRINTF(("FORKEXEC: bltin %p, no_fork %d, owp %p\n", bltin,
2748 2745 no_fork, owp));
2749 DBGPRINTF(("FORKEXEC: bltin %p, f&FEXEC 0x%x, owp %p\n", bltin, 2746 /* Don't fork if it is a lone builtin (not in pipe)
2750 f & FEXEC, owp)); 2747 * OR we are told to _not_ fork */
2751 2748 if ((!bltin || pin || pout) /* not lone bltin AND */
2752 if (!bltin && (f & FEXEC) == 0) { 2749 && !no_fork /* not told to avoid fork */
2753 /* Save values in case the child process alters them */ 2750 ) {
2751 /* Save values in case child alters them after vfork */
2754 hpin = pin; 2752 hpin = pin;
2755 hpout = pout; 2753 hpout = pout;
2756 hwp = *wp; 2754 hwp = *wp;
@@ -2760,9 +2758,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2760 hexecflg = execflg; 2758 hexecflg = execflg;
2761 2759
2762 DBGPRINTF3(("FORKEXEC: calling vfork()...\n")); 2760 DBGPRINTF3(("FORKEXEC: calling vfork()...\n"));
2763
2764 newpid = vfork(); 2761 newpid = vfork();
2765
2766 if (newpid == -1) { 2762 if (newpid == -1) {
2767 DBGPRINTF(("FORKEXEC: ERROR, cannot vfork()!\n")); 2763 DBGPRINTF(("FORKEXEC: ERROR, cannot vfork()!\n"));
2768 return -1; 2764 return -1;
@@ -2783,8 +2779,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2783 } 2779 }
2784 2780
2785 /* Child */ 2781 /* Child */
2786 DBGPRINTF(("FORKEXEC: child process, bltin=%p\n", bltin)); 2782 DBGPRINTF(("FORKEXEC: child process, bltin=%p (%s)\n", bltin, bltin_name));
2787
2788 if (interactive) { 2783 if (interactive) {
2789 signal(SIGINT, SIG_IGN); 2784 signal(SIGINT, SIG_IGN);
2790 signal(SIGQUIT, SIG_IGN); 2785 signal(SIGQUIT, SIG_IGN);
@@ -2802,20 +2797,6 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2802 if (!bltin) 2797 if (!bltin)
2803 export(lookup(cp)); 2798 export(lookup(cp));
2804 2799
2805#if 1
2806 /* How to fix it:
2807 * explicitly pass pin[0] and pout[1] to builtins
2808 * instead of making them rely on fd 0/1,
2809 * and do not xmove_fd(pin[0]/pout[1]) below if bltin != NULL.
2810 */
2811 if ((pin || pout) && bltin && bltin != doexec) {
2812 err("piping to/from shell builtins not yet done");
2813 if (forked)
2814 _exit(-1);
2815 return -1;
2816 }
2817#endif
2818
2819 if (pin) { 2800 if (pin) {
2820 xmove_fd(pin[0], 0); 2801 xmove_fd(pin[0], 0);
2821 if (pin[1] != 0) 2802 if (pin[1] != 0)
@@ -2830,33 +2811,36 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2830 iopp = t->ioact; 2811 iopp = t->ioact;
2831 if (iopp) { 2812 if (iopp) {
2832 if (bltin && bltin != doexec) { 2813 if (bltin && bltin != doexec) {
2833 prs(cp); 2814 prs(bltin_name);
2834 err(": cannot redirect shell command"); 2815 err(": cannot redirect shell command");
2835 if (forked) 2816 if (forked)
2836 _exit(-1); 2817 _exit(-1);
2837 return -1; 2818 return -1;
2838 } 2819 }
2839 while (*iopp) 2820 while (*iopp) {
2840 if (iosetup(*iopp++, pin != NULL, pout != NULL)) { 2821 if (iosetup(*iopp++, pin != NULL, pout != NULL)) {
2841 /* system-detected error */ 2822 /* system-detected error */
2842 if (forked) 2823 if (forked)
2843 _exit(-1); 2824 _exit(-1);
2844 return -1; 2825 return -1;
2845 } 2826 }
2827 }
2846 } 2828 }
2847 2829
2848 if (bltin) { 2830 if (bltin) {
2831 if (forked || pin || pout) {
2832 /* Builtin in pipe: disallowed */
2833 /* TODO: allow "exec"? */
2834 prs(bltin_name);
2835 err(": cannot run builtin as part of pipe");
2836 if (forked)
2837 _exit(-1);
2838 return -1;
2839 }
2849 i = setstatus(bltin(t)); 2840 i = setstatus(bltin(t));
2850 if (forked) 2841 if (forked)
2851 _exit(i); 2842 _exit(i);
2852 DBGPRINTF(("FORKEXEC: returning i=%d\n", i)); 2843 DBGPRINTF(("FORKEXEC: returning i=%d\n", i));
2853/* Builtins in pipes ("ls /dev/null | cd"):
2854 * here "cd" (which is not a child) will return to main msh,
2855 * and we will read from ls's output as if it is our next command!
2856 * Result: "/dev/null: cannot execute"
2857 * and then we reach EOF on stdin and exit.
2858 * See above for possible way to fix this.
2859 */
2860 return i; 2844 return i;
2861 } 2845 }
2862 2846
@@ -2869,7 +2853,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2869 } 2853 }
2870 2854
2871 if (t->type == TPAREN) 2855 if (t->type == TPAREN)
2872 _exit(execute(t->left, NOPIPE, NOPIPE, FEXEC)); 2856 _exit(execute(t->left, NOPIPE, NOPIPE, /* no_fork: */ 1));
2873 if (wp[0] == NULL) 2857 if (wp[0] == NULL)
2874 _exit(0); 2858 _exit(0);
2875 2859
@@ -2880,7 +2864,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
2880 if (!execflg) 2864 if (!execflg)
2881 trap[0] = NULL; 2865 trap[0] = NULL;
2882 2866
2883 DBGPRINTF(("FORKEXEC: calling leave(), pid=%d\n", newpid)); 2867 DBGPRINTF(("FORKEXEC: calling leave(), pid=%d\n", getpid()));
2884 2868
2885 leave(); 2869 leave();
2886 /* NOTREACHED */ 2870 /* NOTREACHED */
@@ -2927,6 +2911,7 @@ static int iosetup(struct ioword *iop, int pipein, int pipeout)
2927 iop->io_flag = IOCLOSE; 2911 iop->io_flag = IOCLOSE;
2928 iop->io_flag &= ~(IOREAD | IOWRITE); 2912 iop->io_flag &= ~(IOREAD | IOWRITE);
2929 } 2913 }
2914
2930 switch (iop->io_flag) { 2915 switch (iop->io_flag) {
2931 case IOREAD: 2916 case IOREAD:
2932 u = open(cp, O_RDONLY); 2917 u = open(cp, O_RDONLY);
@@ -2944,6 +2929,8 @@ static int iosetup(struct ioword *iop, int pipein, int pipeout)
2944 lseek(u, (long) 0, SEEK_END); 2929 lseek(u, (long) 0, SEEK_END);
2945 break; 2930 break;
2946 } 2931 }
2932 /* fall through to creation if >>file doesn't exist */
2933
2947 case IOWRITE: 2934 case IOWRITE:
2948 u = creat(cp, 0666); 2935 u = creat(cp, 0666);
2949 break; 2936 break;
@@ -2956,6 +2943,7 @@ static int iosetup(struct ioword *iop, int pipein, int pipeout)
2956 close(iop->io_unit); 2943 close(iop->io_unit);
2957 return 0; 2944 return 0;
2958 } 2945 }
2946
2959 if (u < 0) { 2947 if (u < 0) {
2960 prs(cp); 2948 prs(cp);
2961 prs(": cannot "); 2949 prs(": cannot ");
@@ -3148,7 +3136,7 @@ static int run(struct ioarg *argp, int (*f) (struct ioarg *))
3148 yynerrs = 0; 3136 yynerrs = 0;
3149 failpt = rt; 3137 failpt = rt;
3150 if (setjmp(failpt) == 0 && yyparse() == 0) 3138 if (setjmp(failpt) == 0 && yyparse() == 0)
3151 rv = execute(outtree, NOPIPE, NOPIPE, 0); 3139 rv = execute(outtree, NOPIPE, NOPIPE, /* no_fork: */ 0);
3152 quitenv(); 3140 quitenv();
3153 } else { 3141 } else {
3154 DBGPRINTF(("RUN: error from newenv()!\n")); 3142 DBGPRINTF(("RUN: error from newenv()!\n"));
@@ -3267,20 +3255,21 @@ static int dologin(struct op *t)
3267 3255
3268static int doumask(struct op *t) 3256static int doumask(struct op *t)
3269{ 3257{
3270 int i, n; 3258 int i;
3271 char *cp; 3259 char *cp;
3272 3260
3273 cp = t->words[1]; 3261 cp = t->words[1];
3274 if (cp == NULL) { 3262 if (cp == NULL) {
3275 i = umask(0); 3263 i = umask(0);
3276 umask(i); 3264 umask(i);
3277 for (n = 3 * 4; (n -= 3) >= 0;) 3265 printf("%04o\n", i);
3278 fputc('0' + ((i >> n) & 07), stderr);
3279 fputc('\n', stderr);
3280 } else { 3266 } else {
3281 for (n = 0; *cp >= '0' && *cp <= '7'; cp++) 3267 i = bb_strtou(cp, NULL, 8);
3282 n = n * 8 + (*cp - '0'); 3268 if (errno) {
3283 umask(n); 3269 err("umask: bad octal number");
3270 return 1;
3271 }
3272 umask(i);
3284 } 3273 }
3285 return 0; 3274 return 0;
3286} 3275}
@@ -3292,14 +3281,15 @@ static int doexec(struct op *t)
3292 xint *ofail; 3281 xint *ofail;
3293 3282
3294 t->ioact = NULL; 3283 t->ioact = NULL;
3295 for (i = 0; (t->words[i] = t->words[i + 1]) != NULL; i++); 3284 for (i = 0; (t->words[i] = t->words[i + 1]) != NULL; i++)
3285 continue;
3296 if (i == 0) 3286 if (i == 0)
3297 return 1; 3287 return 1;
3298 execflg = 1; 3288 execflg = 1;
3299 ofail = failpt; 3289 ofail = failpt;
3300 failpt = ex; 3290 failpt = ex;
3301 if (setjmp(failpt) == 0) 3291 if (setjmp(failpt) == 0)
3302 execute(t, NOPIPE, NOPIPE, FEXEC); 3292 execute(t, NOPIPE, NOPIPE, /* no_fork: */ 1);
3303 failpt = ofail; 3293 failpt = ofail;
3304 execflg = 0; 3294 execflg = 0;
3305 return 1; 3295 return 1;