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
This commit is contained in:
parent
e26b2783a5
commit
7e497527ea
180
shell/msh.c
180
shell/msh.c
@ -86,7 +86,7 @@ static char *itoa(int n)
|
|||||||
# include "busybox.h" /* for applet_names */
|
# include "busybox.h" /* for applet_names */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*#define MSHDEBUG 1*/
|
//#define MSHDEBUG 4
|
||||||
|
|
||||||
#ifdef MSHDEBUG
|
#ifdef MSHDEBUG
|
||||||
int mshdbg = MSHDEBUG;
|
int mshdbg = MSHDEBUG;
|
||||||
@ -244,11 +244,6 @@ static const char *const T_CMD_NAMES[] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* actions determining the environment of a process
|
|
||||||
*/
|
|
||||||
#define FEXEC 1 /* execute without forking */
|
|
||||||
|
|
||||||
#define AREASIZE (90000)
|
#define AREASIZE (90000)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -402,8 +397,6 @@ struct var {
|
|||||||
|
|
||||||
static int yyparse(void);
|
static int yyparse(void);
|
||||||
|
|
||||||
static int execute(struct op *t, int *pin, int *pout, int act);
|
|
||||||
|
|
||||||
|
|
||||||
/* -------- io.h -------- */
|
/* -------- io.h -------- */
|
||||||
/* io buffer */
|
/* io buffer */
|
||||||
@ -495,7 +488,8 @@ static char **getwords(struct wdblock *wb);
|
|||||||
|
|
||||||
/* -------- misc stuff -------- */
|
/* -------- misc stuff -------- */
|
||||||
|
|
||||||
static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp);
|
static int forkexec(struct op *t, int *pin, int *pout, int no_fork, char **wp);
|
||||||
|
static int execute(struct op *t, int *pin, int *pout, int no_fork);
|
||||||
static int iosetup(struct ioword *iop, int pipein, int pipeout);
|
static int iosetup(struct ioword *iop, int pipein, int pipeout);
|
||||||
static void brkset(struct brkcon *bc);
|
static void brkset(struct brkcon *bc);
|
||||||
static int dolabel(struct op *t);
|
static int dolabel(struct op *t);
|
||||||
@ -564,10 +558,13 @@ static const char *const signame[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef int (*builtin_func_ptr)(struct op *);
|
||||||
|
|
||||||
struct builtincmd {
|
struct builtincmd {
|
||||||
const char *name;
|
const char *name;
|
||||||
int (*builtinfunc)(struct op *t);
|
builtin_func_ptr builtinfunc;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct builtincmd builtincmds[] = {
|
static const struct builtincmd builtincmds[] = {
|
||||||
{ "." , dodot },
|
{ "." , dodot },
|
||||||
{ ":" , dolabel },
|
{ ":" , dolabel },
|
||||||
@ -1373,7 +1370,7 @@ static void onecommand(void)
|
|||||||
if (!FLAG['n']) {
|
if (!FLAG['n']) {
|
||||||
DBGPRINTF(("ONECOMMAND: calling execute, t=outtree=%p\n",
|
DBGPRINTF(("ONECOMMAND: calling execute, t=outtree=%p\n",
|
||||||
outtree));
|
outtree));
|
||||||
execute(outtree, NOPIPE, NOPIPE, 0);
|
execute(outtree, NOPIPE, NOPIPE, /* no_fork: */ 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!interactive && intr) {
|
if (!interactive && intr) {
|
||||||
@ -2450,7 +2447,7 @@ static struct op *findcase(struct op *t, const char *w)
|
|||||||
* execute tree
|
* execute tree
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int execute(struct op *t, int *pin, int *pout, int act)
|
static int execute(struct op *t, int *pin, int *pout, int no_fork)
|
||||||
{
|
{
|
||||||
struct op *t1;
|
struct op *t1;
|
||||||
volatile int i, rv, a;
|
volatile int i, rv, a;
|
||||||
@ -2495,17 +2492,17 @@ static int execute(struct op *t, int *pin, int *pout, int act)
|
|||||||
outtree = outtree_save;
|
outtree = outtree_save;
|
||||||
|
|
||||||
if (t->left)
|
if (t->left)
|
||||||
rv = execute(t->left, pin, pout, 0);
|
rv = execute(t->left, pin, pout, /* no_fork: */ 0);
|
||||||
if (t->right)
|
if (t->right)
|
||||||
rv = execute(t->right, pin, pout, 0);
|
rv = execute(t->right, pin, pout, /* no_fork: */ 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TPAREN:
|
case TPAREN:
|
||||||
rv = execute(t->left, pin, pout, 0);
|
rv = execute(t->left, pin, pout, /* no_fork: */ 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TCOM:
|
case TCOM:
|
||||||
rv = forkexec(t, pin, pout, act, wp);
|
rv = forkexec(t, pin, pout, no_fork, wp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TPIPE:
|
case TPIPE:
|
||||||
@ -2517,14 +2514,14 @@ static int execute(struct op *t, int *pin, int *pout, int act)
|
|||||||
break;
|
break;
|
||||||
pv[0] = remap(pv[0]);
|
pv[0] = remap(pv[0]);
|
||||||
pv[1] = remap(pv[1]);
|
pv[1] = remap(pv[1]);
|
||||||
(void) execute(t->left, pin, pv, 0);
|
(void) execute(t->left, pin, pv, /* no_fork: */ 0);
|
||||||
rv = execute(t->right, pv, pout, 0);
|
rv = execute(t->right, pv, pout, /* no_fork: */ 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TLIST:
|
case TLIST:
|
||||||
(void) execute(t->left, pin, pout, 0);
|
(void) execute(t->left, pin, pout, /* no_fork: */ 0);
|
||||||
rv = execute(t->right, pin, pout, 0);
|
rv = execute(t->right, pin, pout, /* no_fork: */ 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TASYNC:
|
case TASYNC:
|
||||||
@ -2544,7 +2541,7 @@ static int execute(struct op *t, int *pin, int *pout, int act)
|
|||||||
close(0);
|
close(0);
|
||||||
xopen(bb_dev_null, O_RDONLY);
|
xopen(bb_dev_null, O_RDONLY);
|
||||||
}
|
}
|
||||||
_exit(execute(t->left, pin, pout, FEXEC));
|
_exit(execute(t->left, pin, pout, /* no_fork: */ 1));
|
||||||
}
|
}
|
||||||
interactive = hinteractive;
|
interactive = hinteractive;
|
||||||
if (i != -1) {
|
if (i != -1) {
|
||||||
@ -2562,10 +2559,10 @@ static int execute(struct op *t, int *pin, int *pout, int act)
|
|||||||
|
|
||||||
case TOR:
|
case TOR:
|
||||||
case TAND:
|
case TAND:
|
||||||
rv = execute(t->left, pin, pout, 0);
|
rv = execute(t->left, pin, pout, /* no_fork: */ 0);
|
||||||
t1 = t->right;
|
t1 = t->right;
|
||||||
if (t1 != NULL && (rv == 0) == (t->type == TAND))
|
if (t1 != NULL && (rv == 0) == (t->type == TAND))
|
||||||
rv = execute(t1, pin, pout, 0);
|
rv = execute(t1, pin, pout, /* no_fork: */ 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TFOR:
|
case TFOR:
|
||||||
@ -2585,7 +2582,7 @@ static int execute(struct op *t, int *pin, int *pout, int act)
|
|||||||
brkset(&bc);
|
brkset(&bc);
|
||||||
for (t1 = t->left; i-- && *wp != NULL;) {
|
for (t1 = t->left; i-- && *wp != NULL;) {
|
||||||
setval(vp, *wp++);
|
setval(vp, *wp++);
|
||||||
rv = execute(t1, pin, pout, 0);
|
rv = execute(t1, pin, pout, /* no_fork: */ 0);
|
||||||
}
|
}
|
||||||
brklist = brklist->nextlev;
|
brklist = brklist->nextlev;
|
||||||
break;
|
break;
|
||||||
@ -2597,17 +2594,17 @@ static int execute(struct op *t, int *pin, int *pout, int act)
|
|||||||
goto broken;
|
goto broken;
|
||||||
brkset(&bc);
|
brkset(&bc);
|
||||||
t1 = t->left;
|
t1 = t->left;
|
||||||
while ((execute(t1, pin, pout, 0) == 0) == (t->type == TWHILE))
|
while ((execute(t1, pin, pout, /* no_fork: */ 0) == 0) == (t->type == TWHILE))
|
||||||
rv = execute(t->right, pin, pout, 0);
|
rv = execute(t->right, pin, pout, /* no_fork: */ 0);
|
||||||
brklist = brklist->nextlev;
|
brklist = brklist->nextlev;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TIF:
|
case TIF:
|
||||||
case TELIF:
|
case TELIF:
|
||||||
if (t->right != NULL) {
|
if (t->right != NULL) {
|
||||||
rv = !execute(t->left, pin, pout, 0) ?
|
rv = !execute(t->left, pin, pout, /* no_fork: */ 0) ?
|
||||||
execute(t->right->left, pin, pout, 0) :
|
execute(t->right->left, pin, pout, /* no_fork: */ 0) :
|
||||||
execute(t->right->right, pin, pout, 0);
|
execute(t->right->right, pin, pout, /* no_fork: */ 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2623,7 +2620,7 @@ static int execute(struct op *t, int *pin, int *pout, int act)
|
|||||||
t1 = findcase(t->left, cp);
|
t1 = findcase(t->left, cp);
|
||||||
if (t1 != NULL) {
|
if (t1 != NULL) {
|
||||||
DBGPRINTF7(("EXECUTE: TCASE, calling execute(t=%p, t1=%p)...\n", t, t1));
|
DBGPRINTF7(("EXECUTE: TCASE, calling execute(t=%p, t1=%p)...\n", t, t1));
|
||||||
rv = execute(t1, pin, pout, 0);
|
rv = execute(t1, pin, pout, /* no_fork: */ 0);
|
||||||
DBGPRINTF7(("EXECUTE: TCASE, back from execute(t=%p, t1=%p)...\n", t, t1));
|
DBGPRINTF7(("EXECUTE: TCASE, back from execute(t=%p, t1=%p)...\n", t, t1));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2641,7 +2638,7 @@ static int execute(struct op *t, int *pin, int *pout, int act)
|
|||||||
if (rv >= 0) {
|
if (rv >= 0) {
|
||||||
t1 = t->left;
|
t1 = t->left;
|
||||||
if (t1) {
|
if (t1) {
|
||||||
rv = execute(t1, pin, pout, 0);
|
rv = execute(t1, pin, pout, /* no_fork: */ 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2669,8 +2666,6 @@ static int execute(struct op *t, int *pin, int *pout, int act)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef int (*builtin_func_ptr)(struct op *);
|
|
||||||
|
|
||||||
static builtin_func_ptr inbuilt(const char *s)
|
static builtin_func_ptr inbuilt(const char *s)
|
||||||
{
|
{
|
||||||
const struct builtincmd *bp;
|
const struct builtincmd *bp;
|
||||||
@ -2681,17 +2676,17 @@ static builtin_func_ptr inbuilt(const char *s)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
|
static int forkexec(struct op *t, int *pin, int *pout, int no_fork, char **wp)
|
||||||
{
|
{
|
||||||
pid_t newpid;
|
pid_t newpid;
|
||||||
int i;
|
int i;
|
||||||
builtin_func_ptr bltin = NULL;
|
builtin_func_ptr bltin = NULL;
|
||||||
int f;
|
const char *bltin_name = NULL;
|
||||||
const char *cp = NULL;
|
const char *cp;
|
||||||
struct ioword **iopp;
|
struct ioword **iopp;
|
||||||
int resetsig;
|
int resetsig;
|
||||||
char **owp;
|
char **owp;
|
||||||
int forked = 0;
|
int forked;
|
||||||
|
|
||||||
int *hpin = pin;
|
int *hpin = pin;
|
||||||
int *hpout = pout;
|
int *hpout = pout;
|
||||||
@ -2712,11 +2707,10 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
|
|||||||
(void) &owp;
|
(void) &owp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DBGPRINTF(("FORKEXEC: t=%p, pin %p, pout %p, act %d\n", t, pin,
|
DBGPRINTF(("FORKEXEC: t=%p, pin %p, pout %p, no_fork %d\n", t, pin,
|
||||||
pout, act));
|
pout, no_fork));
|
||||||
DBGPRINTF7(("FORKEXEC: t->words is %s\n",
|
DBGPRINTF7(("FORKEXEC: t->words is %s\n",
|
||||||
((t->words == NULL) ? "NULL" : t->words[0])));
|
((t->words == NULL) ? "NULL" : t->words[0])));
|
||||||
|
|
||||||
owp = wp;
|
owp = wp;
|
||||||
resetsig = 0;
|
resetsig = 0;
|
||||||
if (t->type == TCOM) {
|
if (t->type == TCOM) {
|
||||||
@ -2725,32 +2719,36 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
|
|||||||
cp = *wp;
|
cp = *wp;
|
||||||
|
|
||||||
/* strip all initial assignments */
|
/* strip all initial assignments */
|
||||||
/* not correct wrt PATH=yyy command etc */
|
/* FIXME: not correct wrt PATH=yyy command etc */
|
||||||
if (FLAG['x']) {
|
if (FLAG['x']) {
|
||||||
DBGPRINTF9(("FORKEXEC: echo'ing, cp=%p, wp=%p, owp=%p\n",
|
DBGPRINTF9(("FORKEXEC: echo'ing, cp=%p, wp=%p, owp=%p\n",
|
||||||
cp, wp, owp));
|
cp, wp, owp));
|
||||||
echo(cp ? wp : owp);
|
echo(cp ? wp : owp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cp == NULL && t->ioact == NULL) {
|
if (cp == NULL) {
|
||||||
while ((cp = *owp++) != NULL && assign(cp, COPYV))
|
if (t->ioact == NULL) {
|
||||||
continue;
|
while ((cp = *owp++) != NULL && assign(cp, COPYV))
|
||||||
DBGPRINTF(("FORKEXEC: returning setstatus()\n"));
|
continue;
|
||||||
return setstatus(0);
|
DBGPRINTF(("FORKEXEC: returning setstatus(0)\n"));
|
||||||
}
|
return setstatus(0);
|
||||||
if (cp != NULL) {
|
}
|
||||||
|
} else { /* cp != NULL */
|
||||||
|
bltin_name = cp;
|
||||||
bltin = inbuilt(cp);
|
bltin = inbuilt(cp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forked = 0;
|
||||||
t->words = wp;
|
t->words = wp;
|
||||||
f = act;
|
DBGPRINTF(("FORKEXEC: bltin %p, no_fork %d, owp %p\n", bltin,
|
||||||
|
no_fork, owp));
|
||||||
DBGPRINTF(("FORKEXEC: bltin %p, f&FEXEC 0x%x, owp %p\n", bltin,
|
/* Don't fork if it is a lone builtin (not in pipe)
|
||||||
f & FEXEC, owp));
|
* OR we are told to _not_ fork */
|
||||||
|
if ((!bltin || pin || pout) /* not lone bltin AND */
|
||||||
if (!bltin && (f & FEXEC) == 0) {
|
&& !no_fork /* not told to avoid fork */
|
||||||
/* Save values in case the child process alters them */
|
) {
|
||||||
|
/* Save values in case child alters them after vfork */
|
||||||
hpin = pin;
|
hpin = pin;
|
||||||
hpout = pout;
|
hpout = pout;
|
||||||
hwp = *wp;
|
hwp = *wp;
|
||||||
@ -2760,9 +2758,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
|
|||||||
hexecflg = execflg;
|
hexecflg = execflg;
|
||||||
|
|
||||||
DBGPRINTF3(("FORKEXEC: calling vfork()...\n"));
|
DBGPRINTF3(("FORKEXEC: calling vfork()...\n"));
|
||||||
|
|
||||||
newpid = vfork();
|
newpid = vfork();
|
||||||
|
|
||||||
if (newpid == -1) {
|
if (newpid == -1) {
|
||||||
DBGPRINTF(("FORKEXEC: ERROR, cannot vfork()!\n"));
|
DBGPRINTF(("FORKEXEC: ERROR, cannot vfork()!\n"));
|
||||||
return -1;
|
return -1;
|
||||||
@ -2783,8 +2779,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Child */
|
/* Child */
|
||||||
DBGPRINTF(("FORKEXEC: child process, bltin=%p\n", bltin));
|
DBGPRINTF(("FORKEXEC: child process, bltin=%p (%s)\n", bltin, bltin_name));
|
||||||
|
|
||||||
if (interactive) {
|
if (interactive) {
|
||||||
signal(SIGINT, SIG_IGN);
|
signal(SIGINT, SIG_IGN);
|
||||||
signal(SIGQUIT, SIG_IGN);
|
signal(SIGQUIT, SIG_IGN);
|
||||||
@ -2802,20 +2797,6 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
|
|||||||
if (!bltin)
|
if (!bltin)
|
||||||
export(lookup(cp));
|
export(lookup(cp));
|
||||||
|
|
||||||
#if 1
|
|
||||||
/* How to fix it:
|
|
||||||
* explicitly pass pin[0] and pout[1] to builtins
|
|
||||||
* instead of making them rely on fd 0/1,
|
|
||||||
* and do not xmove_fd(pin[0]/pout[1]) below if bltin != NULL.
|
|
||||||
*/
|
|
||||||
if ((pin || pout) && bltin && bltin != doexec) {
|
|
||||||
err("piping to/from shell builtins not yet done");
|
|
||||||
if (forked)
|
|
||||||
_exit(-1);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (pin) {
|
if (pin) {
|
||||||
xmove_fd(pin[0], 0);
|
xmove_fd(pin[0], 0);
|
||||||
if (pin[1] != 0)
|
if (pin[1] != 0)
|
||||||
@ -2830,33 +2811,36 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
|
|||||||
iopp = t->ioact;
|
iopp = t->ioact;
|
||||||
if (iopp) {
|
if (iopp) {
|
||||||
if (bltin && bltin != doexec) {
|
if (bltin && bltin != doexec) {
|
||||||
prs(cp);
|
prs(bltin_name);
|
||||||
err(": cannot redirect shell command");
|
err(": cannot redirect shell command");
|
||||||
if (forked)
|
if (forked)
|
||||||
_exit(-1);
|
_exit(-1);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
while (*iopp)
|
while (*iopp) {
|
||||||
if (iosetup(*iopp++, pin != NULL, pout != NULL)) {
|
if (iosetup(*iopp++, pin != NULL, pout != NULL)) {
|
||||||
/* system-detected error */
|
/* system-detected error */
|
||||||
if (forked)
|
if (forked)
|
||||||
_exit(-1);
|
_exit(-1);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bltin) {
|
if (bltin) {
|
||||||
|
if (forked || pin || pout) {
|
||||||
|
/* Builtin in pipe: disallowed */
|
||||||
|
/* TODO: allow "exec"? */
|
||||||
|
prs(bltin_name);
|
||||||
|
err(": cannot run builtin as part of pipe");
|
||||||
|
if (forked)
|
||||||
|
_exit(-1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
i = setstatus(bltin(t));
|
i = setstatus(bltin(t));
|
||||||
if (forked)
|
if (forked)
|
||||||
_exit(i);
|
_exit(i);
|
||||||
DBGPRINTF(("FORKEXEC: returning i=%d\n", i));
|
DBGPRINTF(("FORKEXEC: returning i=%d\n", i));
|
||||||
/* Builtins in pipes ("ls /dev/null | cd"):
|
|
||||||
* here "cd" (which is not a child) will return to main msh,
|
|
||||||
* and we will read from ls's output as if it is our next command!
|
|
||||||
* Result: "/dev/null: cannot execute"
|
|
||||||
* and then we reach EOF on stdin and exit.
|
|
||||||
* See above for possible way to fix this.
|
|
||||||
*/
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2869,7 +2853,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (t->type == TPAREN)
|
if (t->type == TPAREN)
|
||||||
_exit(execute(t->left, NOPIPE, NOPIPE, FEXEC));
|
_exit(execute(t->left, NOPIPE, NOPIPE, /* no_fork: */ 1));
|
||||||
if (wp[0] == NULL)
|
if (wp[0] == NULL)
|
||||||
_exit(0);
|
_exit(0);
|
||||||
|
|
||||||
@ -2880,7 +2864,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int act, char **wp)
|
|||||||
if (!execflg)
|
if (!execflg)
|
||||||
trap[0] = NULL;
|
trap[0] = NULL;
|
||||||
|
|
||||||
DBGPRINTF(("FORKEXEC: calling leave(), pid=%d\n", newpid));
|
DBGPRINTF(("FORKEXEC: calling leave(), pid=%d\n", getpid()));
|
||||||
|
|
||||||
leave();
|
leave();
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
@ -2927,6 +2911,7 @@ static int iosetup(struct ioword *iop, int pipein, int pipeout)
|
|||||||
iop->io_flag = IOCLOSE;
|
iop->io_flag = IOCLOSE;
|
||||||
iop->io_flag &= ~(IOREAD | IOWRITE);
|
iop->io_flag &= ~(IOREAD | IOWRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (iop->io_flag) {
|
switch (iop->io_flag) {
|
||||||
case IOREAD:
|
case IOREAD:
|
||||||
u = open(cp, O_RDONLY);
|
u = open(cp, O_RDONLY);
|
||||||
@ -2944,6 +2929,8 @@ static int iosetup(struct ioword *iop, int pipein, int pipeout)
|
|||||||
lseek(u, (long) 0, SEEK_END);
|
lseek(u, (long) 0, SEEK_END);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* fall through to creation if >>file doesn't exist */
|
||||||
|
|
||||||
case IOWRITE:
|
case IOWRITE:
|
||||||
u = creat(cp, 0666);
|
u = creat(cp, 0666);
|
||||||
break;
|
break;
|
||||||
@ -2956,6 +2943,7 @@ static int iosetup(struct ioword *iop, int pipein, int pipeout)
|
|||||||
close(iop->io_unit);
|
close(iop->io_unit);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u < 0) {
|
if (u < 0) {
|
||||||
prs(cp);
|
prs(cp);
|
||||||
prs(": cannot ");
|
prs(": cannot ");
|
||||||
@ -3148,7 +3136,7 @@ static int run(struct ioarg *argp, int (*f) (struct ioarg *))
|
|||||||
yynerrs = 0;
|
yynerrs = 0;
|
||||||
failpt = rt;
|
failpt = rt;
|
||||||
if (setjmp(failpt) == 0 && yyparse() == 0)
|
if (setjmp(failpt) == 0 && yyparse() == 0)
|
||||||
rv = execute(outtree, NOPIPE, NOPIPE, 0);
|
rv = execute(outtree, NOPIPE, NOPIPE, /* no_fork: */ 0);
|
||||||
quitenv();
|
quitenv();
|
||||||
} else {
|
} else {
|
||||||
DBGPRINTF(("RUN: error from newenv()!\n"));
|
DBGPRINTF(("RUN: error from newenv()!\n"));
|
||||||
@ -3267,20 +3255,21 @@ static int dologin(struct op *t)
|
|||||||
|
|
||||||
static int doumask(struct op *t)
|
static int doumask(struct op *t)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i;
|
||||||
char *cp;
|
char *cp;
|
||||||
|
|
||||||
cp = t->words[1];
|
cp = t->words[1];
|
||||||
if (cp == NULL) {
|
if (cp == NULL) {
|
||||||
i = umask(0);
|
i = umask(0);
|
||||||
umask(i);
|
umask(i);
|
||||||
for (n = 3 * 4; (n -= 3) >= 0;)
|
printf("%04o\n", i);
|
||||||
fputc('0' + ((i >> n) & 07), stderr);
|
|
||||||
fputc('\n', stderr);
|
|
||||||
} else {
|
} else {
|
||||||
for (n = 0; *cp >= '0' && *cp <= '7'; cp++)
|
i = bb_strtou(cp, NULL, 8);
|
||||||
n = n * 8 + (*cp - '0');
|
if (errno) {
|
||||||
umask(n);
|
err("umask: bad octal number");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
umask(i);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3292,14 +3281,15 @@ static int doexec(struct op *t)
|
|||||||
xint *ofail;
|
xint *ofail;
|
||||||
|
|
||||||
t->ioact = NULL;
|
t->ioact = NULL;
|
||||||
for (i = 0; (t->words[i] = t->words[i + 1]) != NULL; i++);
|
for (i = 0; (t->words[i] = t->words[i + 1]) != NULL; i++)
|
||||||
|
continue;
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
return 1;
|
return 1;
|
||||||
execflg = 1;
|
execflg = 1;
|
||||||
ofail = failpt;
|
ofail = failpt;
|
||||||
failpt = ex;
|
failpt = ex;
|
||||||
if (setjmp(failpt) == 0)
|
if (setjmp(failpt) == 0)
|
||||||
execute(t, NOPIPE, NOPIPE, FEXEC);
|
execute(t, NOPIPE, NOPIPE, /* no_fork: */ 1);
|
||||||
failpt = ofail;
|
failpt = ofail;
|
||||||
execflg = 0;
|
execflg = 0;
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user