Exemple #1
0
void
evalstring(char *s, int flags)
{
	union node *n;
	struct stackmark smark;
	int flags_exit;
	int any;

	flags_exit = flags & EV_EXIT;
	flags &= ~EV_EXIT;
	any = 0;
	setstackmark(&smark);
	setinputstring(s, 1);
	while ((n = parsecmd(0)) != NEOF) {
		if (n != NULL && !nflag) {
			if (flags_exit && preadateof())
				evaltree(n, flags | EV_EXIT);
			else
				evaltree(n, flags);
			any = 1;
		}
		popstackmark(&smark);
		setstackmark(&smark);
	}
	popfile();
	popstackmark(&smark);
	if (!any)
		exitstatus = 0;
	if (flags_exit)
		exraise(EXEXIT);
}
Exemple #2
0
static union node *
evalcase(union node *n)
{
	union node *cp;
	union node *patp;
	struct arglist arglist;
	struct stackmark smark;

	setstackmark(&smark);
	arglist.lastp = &arglist.list;
	oexitstatus = exitstatus;
	expandarg(n->ncase.expr, &arglist, EXP_TILDE);
	for (cp = n->ncase.cases ; cp ; cp = cp->nclist.next) {
		for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
			if (casematch(patp, arglist.list->text)) {
				popstackmark(&smark);
				while (cp->nclist.next &&
				    cp->type == NCLISTFALLTHRU &&
				    cp->nclist.body == NULL)
					cp = cp->nclist.next;
				if (cp->nclist.next &&
				    cp->type == NCLISTFALLTHRU)
					return (cp);
				if (cp->nclist.body == NULL)
					exitstatus = 0;
				return (cp->nclist.body);
			}
		}
	}
	popstackmark(&smark);
	exitstatus = 0;
	return (NULL);
}
Exemple #3
0
void
evalstring(char *s, int flags)
{
	union node *n;
	struct stackmark smark;
	int flags_exit;

	flags_exit = flags & EV_EXIT;
	flags &= ~EV_EXIT;
	setstackmark(&smark);
	setinputstring(s, 1);
	while ((n = parsecmd(0)) != NEOF) {
		if (n != NULL) {
			if (flags_exit && preadateof())
				evaltree(n, flags | EV_EXIT);
			else
				evaltree(n, flags);
		}
		popstackmark(&smark);
	}
	popfile();
	popstackmark(&smark);
	if (flags_exit)
		exitshell(exitstatus);
}
Exemple #4
0
void
cmdloop(int top)
{
	union node *n;
	struct stackmark smark;
	int inter;
	int numeof = 0;
	enum skipstate skip;

	TRACE(("cmdloop(%d) called\n", top));
	setstackmark(&smark);
	for (;;) {
		if (pendingsigs)
			dotrap();
		inter = 0;
		if (iflag == 1 && top) {
			inter = 1;
			showjobs(out2, SHOW_CHANGED);
			chkmail(0);
			flushout(&errout);
			nflag = 0;
		}
		n = parsecmd(inter);
		TRACE(("cmdloop: "); showtree(n));
		/* showtree(n); DEBUG */
		if (n == NEOF) {
			if (!top || numeof >= 50)
				break;
			if (nflag)
				break;
			if (!stoppedjobs()) {
				if (!iflag || !Iflag)
					break;
				out2str("\nUse \"exit\" to leave shell.\n");
			}
			numeof++;
		} else if (n != NULL && nflag == 0) {
			job_warning = (job_warning == 2) ? 1 : 0;
			numeof = 0;
			evaltree(n, EV_MORE);
		}
		popstackmark(&smark);
		setstackmark(&smark);

		/*
		 * Any SKIP* can occur here!  SKIP(FUNC|BREAK|CONT) occur when
		 * a dotcmd is in a loop or a function body and appropriate
		 * built-ins occurs in file scope in the sourced file.  Values
		 * other than SKIPFILE are reset by the appropriate eval*()
		 * that contained the dotcmd() call.
		 */
		skip = current_skipstate();
		if (skip != SKIPNONE) {
			if (skip == SKIPFILE)
				stop_skipping();
			break;
		}
	}
	popstackmark(&smark);
}
Exemple #5
0
void
evalstring(char *s)
{
	union node *n;
	struct stackmark smark;

	setstackmark(&smark);
	setinputstring(s, 1);
	while ((n = parsecmd(0)) != NEOF) {
		evaltree(n, 0);
		popstackmark(&smark);
	}
	popfile();
	popstackmark(&smark);
}
Exemple #6
0
Fichier : main.c Projet : cbsd/cbsd
static void
cmdloop(int top)
{
	union node *n;
	struct stackmark smark;
	int inter;
	int numeof = 0;

	TRACE(("cmdloop(%d) called\n", top));
	setstackmark(&smark);
	for (;;) {
		if (pendingsig)
			dotrap();
		inter = 0;
		if (iflag && top) {
			inter++;
			showjobs(1, SHOWJOBS_DEFAULT);
#ifndef CBSD
			chkmail(0);
#endif
			flushout(&output);
		}
		n = parsecmd(inter);
		/* showtree(n); DEBUG */
		if (n == NEOF) {
			if (!top || numeof >= 50)
				break;
			if (!stoppedjobs()) {
				if (!Iflag)
					break;
				out2fmt_flush("\nUse \"exit\" to leave shell.\n");
			}
			numeof++;
		} else if (n != NULL && nflag == 0) {
			job_warning = (job_warning == 2) ? 1 : 0;
			numeof = 0;
			evaltree(n, 0);
		}
		popstackmark(&smark);
		setstackmark(&smark);
		if (evalskip != 0) {
			if (evalskip == SKIPRETURN)
				evalskip = 0;
			break;
		}
	}
	popstackmark(&smark);
}
Exemple #7
0
int
dotcmd(int argc, char **argv)
{
	exitstatus = 0;

	if (argc >= 2) {		/* That's what SVR2 does */
		char *fullname;
		/*
		 * dot_funcnest needs to be 0 when not in a dotcmd, so it
		 * cannot be restored with (funcnest + 1).
		 */
		int dot_funcnest_old;
		struct stackmark smark;

		setstackmark(&smark);
		fullname = find_dot_file(argv[1]);
		setinputfile(fullname, 1);
		commandname = fullname;
		dot_funcnest_old = dot_funcnest;
		dot_funcnest = funcnest + 1;
		cmdloop(0);
		dot_funcnest = dot_funcnest_old;
		popfile();
		popstackmark(&smark);
	}
	return exitstatus;
}
Exemple #8
0
static void
evalcase(union node *n, int flags)
{
	union node *cp;
	union node *patp;
	struct arglist arglist;
	struct stackmark smark;

	setstackmark(&smark);
	arglist.lastp = &arglist.list;
	oexitstatus = exitstatus;
	exitstatus = 0;
	expandarg(n->ncase.expr, &arglist, EXP_TILDE);
	for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
		for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
			if (casematch(patp, arglist.list->text)) {
				if (evalskip == 0) {
					evaltree(cp->nclist.body, flags);
				}
				goto out;
			}
		}
	}
out:
	popstackmark(&smark);
}
Exemple #9
0
STATIC void
evalcase(shinstance *psh, union node *n, int flags)
{
	union node *cp;
	union node *patp;
	struct arglist arglist;
	struct stackmark smark;
	int status = 0;

	setstackmark(psh, &smark);
	arglist.lastp = &arglist.list;
	expandarg(psh, n->ncase.expr, &arglist, EXP_TILDE);
	for (cp = n->ncase.cases ; cp && psh->evalskip == 0 ; cp = cp->nclist.next) {
		for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
			if (casematch(psh, patp, arglist.list->text)) {
				if (psh->evalskip == 0) {
					evaltree(psh, cp->nclist.body, flags);
					status = psh->exitstatus;
				}
				goto out;
			}
		}
	}
out:
	psh->exitstatus = status;
	popstackmark(psh, &smark);
}
Exemple #10
0
void
evalstring(shinstance *psh, char *s, int flag)
{
	union node *n;
	struct stackmark smark;

	setstackmark(psh, &smark);
	setinputstring(psh, s, 1);

	while ((n = parsecmd(psh, 0)) != NEOF) {
		evaltree(psh, n, flag);
		popstackmark(psh, &smark);
	}
	popfile(psh);
	popstackmark(psh, &smark);
}
Exemple #11
0
static void
evalfor(union node *n, int flags)
{
	struct arglist arglist;
	union node *argp;
	struct strlist *sp;
	struct stackmark smark;

	setstackmark(&smark);
	arglist.lastp = &arglist.list;
	for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
		oexitstatus = exitstatus;
		expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
	}
	*arglist.lastp = NULL;

	exitstatus = 0;
	loopnest++;
	for (sp = arglist.list ; sp ; sp = sp->next) {
		setvar(n->nfor.var, sp->text, 0);
		evaltree(n->nfor.body, flags);
		if (evalskip) {
			if (evalskip == SKIPCONT && --skipcount <= 0) {
				evalskip = 0;
				continue;
			}
			if (evalskip == SKIPBREAK && --skipcount <= 0)
				evalskip = 0;
			break;
		}
	}
	loopnest--;
	popstackmark(&smark);
}
Exemple #12
0
void
cmdloop(struct shinstance *psh, int top)
{
	union node *n;
	struct stackmark smark;
	int inter;
	int numeof = 0;

	TRACE((psh, "cmdloop(%d) called\n", top));
	setstackmark(psh, &smark);
	for (;;) {
		if (psh->pendingsigs)
			dotrap(psh);
		inter = 0;
		if (iflag(psh) && top) {
			inter = 1;
			showjobs(psh, psh->out2, SHOW_CHANGED);
			chkmail(psh, 0);
			flushout(&psh->errout);
		}
		n = parsecmd(psh, inter);
		/* showtree(n); DEBUG */
		if (n == NEOF) {
			if (!top || numeof >= 50)
				break;
			if (!stoppedjobs(psh)) {
				if (!Iflag(psh))
					break;
				out2str(psh, "\nUse \"exit\" to leave shell.\n");
			}
			numeof++;
		} else if (n != NULL && nflag(psh) == 0) {
			psh->job_warning = (psh->job_warning == 2) ? 1 : 0;
			numeof = 0;
			evaltree(psh, n, 0);
		}
		popstackmark(psh, &smark);
		setstackmark(psh, &smark);
		if (psh->evalskip == SKIPFILE) {
			psh->evalskip = 0;
			break;
		}
	}
	popstackmark(psh, &smark);
}
Exemple #13
0
void
cmdloop(int top)
{
	union node *n;
	struct stackmark smark;
	int inter;
	int numeof = 0;

	TRACE(("cmdloop(%d) called\n", top));
	setstackmark(&smark);
	for (;;) {
		if (pendingsigs)
			dotrap();
		inter = 0;
		if (iflag && top) {
			inter = 1;
			showjobs(out2, SHOW_CHANGED);
			chkmail(0);
			flushout(&errout);
		}
		n = parsecmd(inter);
		/* showtree(n); DEBUG */
		if (n == NEOF) {
			if (!top || numeof >= 50)
				break;
			if (!stoppedjobs()) {
				if (!Iflag)
					break;
				out2str("\nUse \"exit\" to leave shell.\n");
			}
			numeof++;
		} else if (n != NULL && nflag == 0) {
			job_warning = (job_warning == 2) ? 1 : 0;
			numeof = 0;
			evaltree(n, 0);
		}
		popstackmark(&smark);
		setstackmark(&smark);
		if (evalskip == SKIPFILE) {
			evalskip = 0;
			break;
		}
	}
	popstackmark(&smark);
}
Exemple #14
0
void
evalstring(char *s, int flag)
{
	union node *n;
	struct stackmark smark;

	setstackmark(&smark);
	setinputstring(s, 1);

	while ((n = parsecmd(0)) != NEOF) {
		TRACE(("evalstring: "); showtree(n));
		if (nflag == 0)
			evaltree(n, flag);
		popstackmark(&smark);
	}
	popfile();
	popstackmark(&smark);
}
Exemple #15
0
void
evalbackcmd(union node *n, struct backcmd *result)
{
	int pip[2];
	struct job *jp;
	struct stackmark smark;		/* unnecessary */

	setstackmark(&smark);
	result->fd = -1;
	result->buf = NULL;
	result->nleft = 0;
	result->jp = NULL;
	if (nflag || n == NULL) {
		goto out;
	}
#ifdef notyet
	/*
	 * For now we disable executing builtins in the same
	 * context as the shell, because we are not keeping
	 * enough state to recover from changes that are
	 * supposed only to affect subshells. eg. echo "`cd /`"
	 */
	if (n->type == NCMD) {
		exitstatus = oexitstatus;
		evalcommand(n, EV_BACKCMD, result);
	} else
#endif
	{
		INTOFF;
		if (sh_pipe(pip) < 0)
			error("Pipe call failed");
		jp = makejob(n, 1);
		if (forkshell(jp, n, FORK_NOJOB) == 0) {
			FORCEINTON;
			close(pip[0]);
			if (pip[1] != 1) {
				close(1);
				copyfd(pip[1], 1, 1, 0);
				close(pip[1]);
			}
			eflag = 0;
			evaltree(n, EV_EXIT);
			/* NOTREACHED */
		}
		close(pip[1]);
		result->fd = pip[0];
		result->jp = jp;
		INTON;
	}
out:
	popstackmark(&smark);
	TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
		result->fd, result->buf, result->nleft, result->jp));
}
Exemple #16
0
void
chkmail(void)
{
	const char *mpath;
	char *p;
	char *q;
	time_t *mtp;
	struct stackmark smark;
#ifdef WINDOWS
	struct stat statb;
#else
	struct stat64 statb;
#endif

	setstackmark(&smark);
	mpath = mpathset() ? mpathval() : mailval();
	for (mtp = mailtime; mtp < mailtime + MAXMBOXES; mtp++) {
		p = padvance(&mpath, nullstr);
		if (p == NULL)
			break;
		if (*p == '\0')
			continue;
		for (q = p ; *q ; q++);
#ifdef DEBUG
		if (q[-1] != '/')
			abort();
#endif
		q[-1] = '\0';			/* delete trailing '/' */
#ifdef WINDOWS
		if (stat(p, &statb) < 0) {
#else
		if (stat64(p, &statb) < 0) {
#endif
			*mtp = 0;
			continue;
		}
		if (!changed && statb.st_mtime != *mtp) {
			outfmt(
				&errout, snlfmt,
				pathopt ? pathopt : "you have mail"
			);
		}
		*mtp = statb.st_mtime;
	}
	changed = 0;
	popstackmark(&smark);
}


void
changemail(const char *val)
{
	changed++;
}
Exemple #17
0
static int
cmdloop(int top)
{
	union node *n;
	struct stackmark smark;
	int inter;
	int status = 0;
	int numeof = 0;

	TRACE(("cmdloop(%d) called\n", top));
#ifdef HETIO
	if(iflag && top)
		hetio_init();
#endif
	for (;;) {
		int skip;

		setstackmark(&smark);
		if (jobctl)
			showjobs(out2, SHOW_CHANGED);
		inter = 0;
		if (iflag && top) {
			inter++;
			chkmail();
		}
		n = parsecmd(inter);
		/* showtree(n); DEBUG */
		if (n == NEOF) {
			if (!top || numeof >= 50)
				break;
			if (!stoppedjobs()) {
				if (!Iflag)
					break;
				out2str("\nUse \"exit\" to leave shell.\n");
			}
			numeof++;
		} else if (nflag == 0) {
			job_warning = (job_warning == 2) ? 1 : 0;
			numeof = 0;
			evaltree(n, 0);
			status = exitstatus;
		}
		popstackmark(&smark);

		skip = evalskip;
		if (skip) {
			evalskip &= ~(SKIPFUNC | SKIPFUNCDEF);
			break;
		}
	}

	return status;
}
Exemple #18
0
void
chkmail(int32_t silent)
{
	int32_t i;
	const_cstring_t mpath;
	cstring_t p;
	cstring_t q;
	struct stackmark smark;
	struct stat statb;
	if (silent)
		nmboxes = 10;
	if (nmboxes == 0)
		return;
	setstackmark(&smark);
	mpath = mpathset() ? mpathval() : mailval();
	for (i = 0 ; i < nmboxes ; i++)
	{
		p = padvance(&mpath, nullstr);
		if (p == NULL)
			break;
		if (*p == '\0')
			continue;
		for (q = p ; *q ; q++);
		if (q[-1] != '/')
			abort();
		q[-1] = '\0';			/* delete trailing '/' */
#ifdef notdef /* this is what the System V shell claims to do (it lies) */
		if (stat(p, &statb) < 0)
			statb.st_mtime = 0;
		if (statb.st_mtime > mailtime[i] && ! silent)
		{
			out2str(pathopt ? pathopt : "you have mail");
			out2c('\n');
		}
		mailtime[i] = statb.st_mtime;
#else /* this is what it should do */
		if (stat(p, &statb) < 0)
			statb.st_size = 0;
		if (statb.st_size > mailtime[i] && ! silent)
		{
			out2str(pathopt ? pathopt : "you have mail");
			out2c('\n');
		}
		mailtime[i] = statb.st_size;
#endif
	}
	nmboxes = i;
	popstackmark(&smark);
}
Exemple #19
0
int32_t
casematch(union node* pattern, const_cstring_t val)
{
    struct stackmark smark;
    int32_t result;
    cstring_t p;
    setstackmark(&smark);
    argbackq = pattern->narg.backquote;
    STARTSTACKSTR(expdest);
    ifslastp = NULL;
    argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
    STPUTC('\0', expdest);
    p = grabstackstr(expdest);
    result = patmatch(p, val, 0);
    popstackmark(&smark);
    return result;
}
Exemple #20
0
int
casematch(union node *pattern, const char *val)
{
	struct stackmark smark;
	int result;
	char *p;

	setstackmark(&smark);
	argbackq = pattern->narg.backquote;
	STARTSTACKSTR(expdest);
	argstr(pattern->narg.text, EXP_TILDE | EXP_CASE, NULL);
	STPUTC('\0', expdest);
	p = grabstackstr(expdest);
	result = patmatch(p, val);
	popstackmark(&smark);
	return result;
}
Exemple #21
0
int
casematch(shinstance *psh, union node *pattern, char *val)
{
	struct stackmark smark;
	int result;
	char *p;

	setstackmark(psh, &smark);
	psh->argbackq = pattern->narg.backquote;
	STARTSTACKSTR(psh, psh->expdest);
	psh->ifslastp = NULL;
	argstr(psh, pattern->narg.text, EXP_TILDE | EXP_CASE);
	STPUTC(psh, '\0', psh->expdest);
	p = grabstackstr(psh, psh->expdest);
	result = patmatch(psh, p, val, 0);
	popstackmark(psh, &smark);
	return result;
}
arith_t arith(const char *s)
{
	struct stackmark smark;
	arith_t result;

	setstackmark(&smark);

	arith_buf = arith_startbuf = s;

	result = assignment(yylex(), 0);

	if (last_token)
		yyerror("expecting EOF");

	popstackmark(&smark);

	return result;
}
Exemple #23
0
int
dotcmd(struct shinstance *psh, int argc, char **argv)
{
	psh->exitstatus = 0;

	if (argc >= 2) {		/* That's what SVR2 does */
		char *fullname;
		struct stackmark smark;

		setstackmark(psh, &smark);
		fullname = find_dot_file(psh, argv[1]);
		setinputfile(psh, fullname, 1);
		psh->commandname = fullname;
		cmdloop(psh, 0);
		popfile(psh);
		popstackmark(psh, &smark);
	}
	return psh->exitstatus;
}
Exemple #24
0
int
dotcmd(int argc, char **argv)
{
	exitstatus = 0;

	if (argc >= 2) {		/* That's what SVR2 does */
		char *fullname;
		struct stackmark smark;

		setstackmark(&smark);
		fullname = find_dot_file(argv[1]);
		setinputfile(fullname, 1);
		commandname = fullname;
		cmdloop(0);
		popfile();
		popstackmark(&smark);
	}
	return exitstatus;
}
Exemple #25
0
STATIC void
evalfor(union node *n, int flags)
{
	struct arglist arglist;
	union node *argp;
	struct strlist *sp;
	struct stackmark smark;
	int status;

	status = nflag ? exitstatus : 0;

	setstackmark(&smark);
	arglist.lastp = &arglist.list;
	for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
		expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
		if (evalskip)
			goto out;
	}
	*arglist.lastp = NULL;

	loopnest++;
	for (sp = arglist.list ; sp ; sp = sp->next) {
		setvar(n->nfor.var, sp->text, 0);
		evaltree(n->nfor.body, flags & EV_TESTED);
		status = exitstatus;
		if (nflag)
			break;
		if (evalskip) {
			if (evalskip == SKIPCONT && --skipcount <= 0) {
				evalskip = SKIPNONE;
				continue;
			}
			if (evalskip == SKIPBREAK && --skipcount <= 0)
				evalskip = SKIPNONE;
			break;
		}
	}
	loopnest--;
	exitstatus = status;
out:
	popstackmark(&smark);
}
Exemple #26
0
void
evalbackcmd(union node *n, struct backcmd *result)
{
	int pip[2];
	struct job *jp;
	struct stackmark smark;		/* unnecessary */

	setstackmark(&smark);
	result->fd = -1;
	result->buf = NULL;
	result->nleft = 0;
	result->jp = NULL;
	if (n == NULL) {
		exitstatus = 0;
		goto out;
	}
	if (n->type == NCMD) {
		exitstatus = oexitstatus;
		evalcommand(n, EV_BACKCMD, result);
	} else {
		exitstatus = 0;
		if (pipe(pip) < 0)
			error("Pipe call failed: %s", strerror(errno));
		jp = makejob(n, 1);
		if (forkshell(jp, n, FORK_NOJOB) == 0) {
			FORCEINTON;
			close(pip[0]);
			if (pip[1] != 1) {
				dup2(pip[1], 1);
				close(pip[1]);
			}
			evaltree(n, EV_EXIT);
		}
		close(pip[1]);
		result->fd = pip[0];
		result->jp = jp;
	}
out:
	popstackmark(&smark);
	TRACE(("evalbackcmd done: fd=%d buf=%p nleft=%d jp=%p\n",
		result->fd, result->buf, result->nleft, result->jp));
}
Exemple #27
0
int
evalstring(char *s, int flags)
{
	union node *n;
	struct stackmark smark;
	int status;

	setinputstring(s);
	setstackmark(&smark);

	status = 0;
	while ((n = parsecmd(0)) != NEOF) {
		evaltree(n, flags);
		status = exitstatus;
		popstackmark(&smark);
		if (evalskip)
			break;
	}
	popfile();

	return status;
}
Exemple #28
0
STATIC void
evalfor(shinstance *psh, union node *n, int flags)
{
	struct arglist arglist;
	union node *argp;
	struct strlist *sp;
	struct stackmark smark;
	int status = 0;

	setstackmark(psh, &smark);
	arglist.lastp = &arglist.list;
	for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
		expandarg(psh, argp, &arglist, EXP_FULL | EXP_TILDE);
		if (psh->evalskip)
			goto out;
	}
	*arglist.lastp = NULL;

	psh->loopnest++;
	for (sp = arglist.list ; sp ; sp = sp->next) {
		setvar(psh, n->nfor.var, sp->text, 0);
		evaltree(psh, n->nfor.body, flags & EV_TESTED);
		status = psh->exitstatus;
		if (psh->evalskip) {
			if (psh->evalskip == SKIPCONT && --psh->skipcount <= 0) {
				psh->evalskip = 0;
				continue;
			}
			if (psh->evalskip == SKIPBREAK && --psh->skipcount <= 0)
				psh->evalskip = 0;
			break;
		}
	}
	psh->loopnest--;
	psh->exitstatus = status;
out:
	popstackmark(psh, &smark);
}
Exemple #29
0
void
evalbackcmd(union node *n, struct backcmd *result)
{
	int pip[2];
	struct job *jp;
	struct stackmark smark;
	struct jmploc jmploc;
	struct jmploc *savehandler;
	struct localvar *savelocalvars;

	setstackmark(&smark);
	result->fd = -1;
	result->buf = NULL;
	result->nleft = 0;
	result->jp = NULL;
	if (n == NULL) {
		exitstatus = 0;
		goto out;
	}
	exitstatus = oexitstatus;
	if (is_valid_fast_cmdsubst(n)) {
		savelocalvars = localvars;
		localvars = NULL;
		forcelocal++;
		savehandler = handler;
		if (setjmp(jmploc.loc)) {
			if (exception == EXERROR || exception == EXEXEC)
				exitstatus = 2;
			else if (exception != 0) {
				handler = savehandler;
				forcelocal--;
				poplocalvars();
				localvars = savelocalvars;
				longjmp(handler->loc, 1);
			}
		} else {
			handler = &jmploc;
			evalcommand(n, EV_BACKCMD, result);
		}
		handler = savehandler;
		forcelocal--;
		poplocalvars();
		localvars = savelocalvars;
	} else {
		if (pipe(pip) < 0)
			error("Pipe call failed: %s", strerror(errno));
		jp = makejob(n, 1);
		if (forkshell(jp, n, FORK_NOJOB) == 0) {
			FORCEINTON;
			close(pip[0]);
			if (pip[1] != 1) {
				dup2(pip[1], 1);
				close(pip[1]);
			}
			evaltree(n, EV_EXIT);
		}
		close(pip[1]);
		result->fd = pip[0];
		result->jp = jp;
	}
out:
	popstackmark(&smark);
	TRACE(("evalbackcmd done: fd=%d buf=%p nleft=%d jp=%p\n",
		result->fd, result->buf, result->nleft, result->jp));
}
Exemple #30
0
void
evaltree(union node *n, int flags)
{
	int do_etest;
	union node *next;
	struct stackmark smark;

	setstackmark(&smark);
	do_etest = 0;
	if (n == NULL) {
		TRACE(("evaltree(NULL) called\n"));
		exitstatus = 0;
		goto out;
	}
	do {
		next = NULL;
#ifndef NO_HISTORY
		displayhist = 1;	/* show history substitutions done with fc */
#endif
		TRACE(("evaltree(%p: %d) called\n", (void *)n, n->type));
		switch (n->type) {
		case NSEMI:
			evaltree(n->nbinary.ch1, flags & ~EV_EXIT);
			if (evalskip)
				goto out;
			next = n->nbinary.ch2;
			break;
		case NAND:
			evaltree(n->nbinary.ch1, EV_TESTED);
			if (evalskip || exitstatus != 0) {
				goto out;
			}
			next = n->nbinary.ch2;
			break;
		case NOR:
			evaltree(n->nbinary.ch1, EV_TESTED);
			if (evalskip || exitstatus == 0)
				goto out;
			next = n->nbinary.ch2;
			break;
		case NREDIR:
			evalredir(n, flags);
			break;
		case NSUBSHELL:
			evalsubshell(n, flags);
			do_etest = !(flags & EV_TESTED);
			break;
		case NBACKGND:
			evalsubshell(n, flags);
			break;
		case NIF: {
			evaltree(n->nif.test, EV_TESTED);
			if (evalskip)
				goto out;
			if (exitstatus == 0)
				next = n->nif.ifpart;
			else if (n->nif.elsepart)
				next = n->nif.elsepart;
			else
				exitstatus = 0;
			break;
		}
		case NWHILE:
		case NUNTIL:
			evalloop(n, flags & ~EV_EXIT);
			break;
		case NFOR:
			evalfor(n, flags & ~EV_EXIT);
			break;
		case NCASE:
			next = evalcase(n);
			break;
		case NCLIST:
			next = n->nclist.body;
			break;
		case NCLISTFALLTHRU:
			if (n->nclist.body) {
				evaltree(n->nclist.body, flags & ~EV_EXIT);
				if (evalskip)
					goto out;
			}
			next = n->nclist.next;
			break;
		case NDEFUN:
			defun(n->narg.text, n->narg.next);
			exitstatus = 0;
			break;
		case NNOT:
			evaltree(n->nnot.com, EV_TESTED);
			if (evalskip)
				goto out;
			exitstatus = !exitstatus;
			break;

		case NPIPE:
			evalpipe(n);
			do_etest = !(flags & EV_TESTED);
			break;
		case NCMD:
			evalcommand(n, flags, (struct backcmd *)NULL);
			do_etest = !(flags & EV_TESTED);
			break;
		default:
			out1fmt("Node type = %d\n", n->type);
			flushout(&output);
			break;
		}
		n = next;
		popstackmark(&smark);
		setstackmark(&smark);
	} while (n != NULL);
out:
	popstackmark(&smark);
	if (pendingsig)
		dotrap();
	if (eflag && exitstatus != 0 && do_etest)
		exitshell(exitstatus);
	if (flags & EV_EXIT)
		exraise(EXEXIT);
}