Example #1
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));
}
Example #2
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));
}
Example #3
0
File: eval.c Project: dpl0/soc2013
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));
}
Example #4
0
File: eval.c Project: dpl0/soc2013
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);
}
Example #5
0
File: eval.c Project: chenguo/dash
void
evaltree(union node *n, int flags)
{
	int checkexit = 0;
	void (*evalfn)(union node *, int);
	unsigned isor;
	int status;
	if (n == NULL) {
		//TRACE(("evaltree(NULL) called\n"));
		goto out;
	}
#ifndef SMALL
	displayhist = 1;	/* show history substitutions done with fc */
#endif
	TRACE(("pid %d, evaltree(%p: %d, %d, %p) called\n",
	    getpid(), n, n->type, flags));
	switch (n->type) {
	default:
#ifdef DEBUG
#ifndef USE_GLIBC_STDIO
		flushout(out1);
#endif
		break;
#endif
	case NNOT:
		evaltree(n->nnot.com, EV_TESTED);
		status = !exitstatus;
		goto setstatus;
	case NREDIR:
		expredir(n->nredir.redirect);
		status = redirectsafe(n->nredir.redirect, REDIR_PUSH);
		if (!status) {
			evaltree(n->nredir.n, flags & EV_TESTED);
			status = exitstatus;
		}
		popredir(0);
		goto setstatus;
	case NCMD:
#ifdef notyet
		if (eflag && !(flags & EV_TESTED))
			checkexit = ~0;
		evalcommand(n, flags, (struct backcmd *)NULL);
		break;
#else
		evalfn = evalcommand;
checkexit:
		if (eflag && !(flags & EV_TESTED))
			checkexit = ~0;
		goto calleval;
#endif
	case NFOR:
		evalfn = evalfor;
		goto calleval;
	case NWHILE:
	case NUNTIL:
		evalfn = evalloop;
		goto calleval;
	case NSUBSHELL:
	case NBACKGND:
		evalfn = evalsubshell;
		evalsubshell (n, flags);
	case NPIPE:
		evalfn = evalpipe;
#ifdef notyet
		if (eflag && !(flags & EV_TESTED))
			checkexit = ~0;
		goto calleval;
#else
		goto checkexit;
#endif
	case NCASE:
		evalfn = evalcase;
		goto calleval;
	case NAND:
	case NOR:
	case NSEMI:
#if NAND + 1 != NOR
#error NAND + 1 != NOR
#endif
#if NOR + 1 != NSEMI
#error NOR + 1 != NSEMI
#endif
		isor = n->type - NAND;
		evaltree(
			n->nbinary.ch1,
			(flags | ((isor >> 1) - 1)) & EV_TESTED
		);
		if (!exitstatus == isor)
			break;
		if (!evalskip) {
			n = n->nbinary.ch2;
evaln:
			evaltree(n, flags);
			break;
calleval:
			evalfn(n, flags);
			break;
		}
		break;
	case NIF:
		evaltree(n->nif.test, EV_TESTED);
		if (evalskip)
			break;
		if (exitstatus == 0) {
			n = n->nif.ifpart;
			goto evaln;
		} else if (n->nif.elsepart) {
			n = n->nif.elsepart;
			goto evaln;
		}
		goto success;
	case NDEFUN:
		defun(n->narg.text, n->narg.next);
success:
		status = 0;
setstatus:
		exitstatus = status;
		break;
	}
out:
	if ((checkexit & exitstatus) ||
	    (pendingsigs && dotrap()) ||
	    (flags & EV_EXIT))
		exraise(EXEXIT);
}
Example #6
0
void
evaltree(union node *n, int flags)
{
	int do_etest;

	do_etest = 0;
	if (n == NULL) {
		TRACE(("evaltree(NULL) called\n"));
		exitstatus = 0;
		goto out;
	}
#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;
		evaltree(n->nbinary.ch2, flags);
		break;
	case NAND:
		evaltree(n->nbinary.ch1, EV_TESTED);
		if (evalskip || exitstatus != 0) {
			goto out;
		}
		evaltree(n->nbinary.ch2, flags);
		break;
	case NOR:
		evaltree(n->nbinary.ch1, EV_TESTED);
		if (evalskip || exitstatus == 0)
			goto out;
		evaltree(n->nbinary.ch2, flags);
		break;
	case NREDIR:
		oexitstatus = exitstatus;
		expredir(n->nredir.redirect);
		redirect(n->nredir.redirect, REDIR_PUSH);
		evaltree(n->nredir.n, flags);
		popredir();
		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)
			evaltree(n->nif.ifpart, flags);
		else if (n->nif.elsepart)
			evaltree(n->nif.elsepart, flags);
		else
			exitstatus = 0;
		break;
	}
	case NWHILE:
	case NUNTIL:
		evalloop(n, flags & ~EV_EXIT);
		break;
	case NFOR:
		evalfor(n, flags & ~EV_EXIT);
		break;
	case NCASE:
		evalcase(n, flags);
		break;
	case NDEFUN:
		defun(n->narg.text, n->narg.next);
		exitstatus = 0;
		break;
	case NNOT:
		evaltree(n->nnot.com, EV_TESTED);
		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;
	}
out:
	if (pendingsigs)
		dotrap();
	if ((flags & EV_EXIT) || (eflag && exitstatus != 0 && do_etest))
		exitshell(exitstatus);
}
Example #7
0
void
evaltree(shinstance *psh, union node *n, int flags)
{
	if (n == NULL) {
		TRACE((psh, "evaltree(NULL) called\n"));
		psh->exitstatus = 0;
		goto out;
	}
#ifndef SMALL
	psh->displayhist = 1;	/* show history substitutions done with fc */
#endif
	TRACE((psh, "pid %d, evaltree(%p: %d, %d) called\n",
	       sh_getpid(psh), n, n->type, flags));
	switch (n->type) {
	case NSEMI:
		evaltree(psh, n->nbinary.ch1, flags & EV_TESTED);
		if (psh->evalskip)
			goto out;
		evaltree(psh, n->nbinary.ch2, flags);
		break;
	case NAND:
		evaltree(psh, n->nbinary.ch1, EV_TESTED);
		if (psh->evalskip || psh->exitstatus != 0)
			goto out;
		evaltree(psh, n->nbinary.ch2, flags);
		break;
	case NOR:
		evaltree(psh, n->nbinary.ch1, EV_TESTED);
		if (psh->evalskip || psh->exitstatus == 0)
			goto out;
		evaltree(psh, n->nbinary.ch2, flags);
		break;
	case NREDIR:
		expredir(psh, n->nredir.redirect);
		redirect(psh, n->nredir.redirect, REDIR_PUSH);
		evaltree(psh, n->nredir.n, flags);
		popredir(psh);
		break;
	case NSUBSHELL:
		evalsubshell(psh, n, flags);
		break;
	case NBACKGND:
		evalsubshell(psh, n, flags);
		break;
	case NIF: {
		evaltree(psh, n->nif.test, EV_TESTED);
		if (psh->evalskip)
			goto out;
		if (psh->exitstatus == 0)
			evaltree(psh, n->nif.ifpart, flags);
		else if (n->nif.elsepart)
			evaltree(psh, n->nif.elsepart, flags);
		else
			psh->exitstatus = 0;
		break;
	}
	case NWHILE:
	case NUNTIL:
		evalloop(psh, n, flags);
		break;
	case NFOR:
		evalfor(psh, n, flags);
		break;
	case NCASE:
		evalcase(psh, n, flags);
		break;
	case NDEFUN:
		defun(psh, n->narg.text, n->narg.next);
		psh->exitstatus = 0;
		break;
	case NNOT:
		evaltree(psh, n->nnot.com, EV_TESTED);
		psh->exitstatus = !psh->exitstatus;
		break;
	case NPIPE:
		evalpipe(psh, n);
		break;
	case NCMD:
		evalcommand(psh, n, flags, (struct backcmd *)NULL);
		break;
	default:
		out1fmt(psh, "Node type = %d\n", n->type);
		flushout(&psh->output);
		break;
	}
out:
	if (psh->pendingsigs)
		dotrap(psh);
	if ((flags & EV_EXIT) != 0)
		exitshell(psh, psh->exitstatus);
}
Example #8
0
void
evaltree(union node *n, int flags)
{
	bool do_etest;

	do_etest = false;
	if (n == NULL || nflag) {
		TRACE(("evaltree(%s) called\n", n == NULL ? "NULL" : "-n"));
		if (nflag == 0)
			exitstatus = 0;
		goto out;
	}
#ifndef SMALL
	displayhist = 1;	/* show history substitutions done with fc */
#endif
#ifdef NODETYPENAME
	TRACE(("pid %d, evaltree(%p: %s(%d), %#x) called\n",
	    getpid(), n, NODETYPENAME(n->type), n->type, flags));
#else
	TRACE(("pid %d, evaltree(%p: %d, %#x) called\n",
	    getpid(), n, n->type, flags));
#endif
	switch (n->type) {
	case NSEMI:
		evaltree(n->nbinary.ch1, flags & EV_TESTED);
		if (nflag || evalskip)
			goto out;
		evaltree(n->nbinary.ch2, flags);
		break;
	case NAND:
		evaltree(n->nbinary.ch1, EV_TESTED);
		if (nflag || evalskip || exitstatus != 0)
			goto out;
		evaltree(n->nbinary.ch2, flags);
		break;
	case NOR:
		evaltree(n->nbinary.ch1, EV_TESTED);
		if (nflag || evalskip || exitstatus == 0)
			goto out;
		evaltree(n->nbinary.ch2, flags);
		break;
	case NREDIR:
		expredir(n->nredir.redirect);
		redirect(n->nredir.redirect, REDIR_PUSH | REDIR_KEEP);
		evaltree(n->nredir.n, flags);
		popredir();
		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 (nflag || evalskip)
			goto out;
		if (exitstatus == 0)
			evaltree(n->nif.ifpart, flags);
		else if (n->nif.elsepart)
			evaltree(n->nif.elsepart, flags);
		else
			exitstatus = 0;
		break;
	}
	case NWHILE:
	case NUNTIL:
		evalloop(n, flags);
		break;
	case NFOR:
		evalfor(n, flags);
		break;
	case NCASE:
		evalcase(n, flags);
		break;
	case NDEFUN:
		defun(n->narg.text, n->narg.next);
		exitstatus = 0;
		break;
	case NNOT:
		evaltree(n->nnot.com, EV_TESTED);
		exitstatus = !exitstatus;
		break;
	case NPIPE:
		evalpipe(n);
		do_etest = !(flags & EV_TESTED);
		break;
	case NCMD:
		evalcommand(n, flags, NULL);
		do_etest = !(flags & EV_TESTED);
		break;
	default:
#ifdef NODETYPENAME
		out1fmt("Node type = %d(%s)\n", n->type, NODETYPENAME(n->type));
#else
		out1fmt("Node type = %d\n", n->type);
#endif
		flushout(&output);
		break;
	}
out:
	if (pendingsigs)
		dotrap();
	if ((flags & EV_EXIT) != 0 || (eflag && exitstatus != 0 && do_etest))
		exitshell(exitstatus);
}