evalfun(struct funcnode *func, int argc, char **argv, int flags)
{
	volatile struct shparam saveparam;
	struct jmploc *volatile savehandler;
	struct jmploc jmploc;
	int e;
	int savefuncline;
	int saveloopnest;

	saveparam = shellparam;
	savefuncline = funcline;
	saveloopnest = loopnest;
	savehandler = handler;
	if ((e = setjmp(jmploc.loc))) {
		goto funcdone;
	}
	INTOFF;
	handler = &jmploc;
	shellparam.malloc = 0;
	func->count++;
	funcline = func->n.ndefun.linno;
	loopnest = 0;
	INTON;
	shellparam.nparam = argc - 1;
	shellparam.p = argv + 1;
	shellparam.optind = 1;
	shellparam.optoff = -1;
	evaltree(func->n.ndefun.body, flags & EV_TESTED);
funcdone:
	INTOFF;
	loopnest = saveloopnest;
	funcline = savefuncline;
	freefunc(func);
	freeparam(&shellparam);
	shellparam = saveparam;
	handler = savehandler;
	INTON;
	evalskip &= ~(SKIPFUNC | SKIPFUNCDEF);
	return e;
}
evalfun(struct funcnode *func, int argc, char **argv, int flags)
{
	volatile struct shparam saveparam;
	struct jmploc *volatile savehandler;
	struct jmploc jmploc;
	int e;
	int savefuncline;
	int saveloopnest;

	saveparam = shellparam;
	savefuncline = funcline;
	saveloopnest = loopnest;
	savehandler = handler;
	if ((e = setjmp(jmploc.loc))) {
		goto funcdone;
	}
	INTOFF;
	handler = &jmploc;
	shellparam.malloc = 0;
	func->count++;
	funcline = func->n.ndefun.linno;
	loopnest = 0;
	INTON;
	shellparam.nparam = argc - 1;
	shellparam.p = argv + 1;
	shellparam.optind = 1;
	shellparam.optoff = -1;
	evaltree(func->n.ndefun.body, flags & EV_TESTED);
funcdone:
	INTOFF;
	loopnest = saveloopnest;
	funcline = savefuncline;
	freefunc(func);
	freeparam(&shellparam);
	shellparam = saveparam;
	handler = savehandler;
	INTON;
	evalskip &= ~(SKIPFUNC | SKIPFUNCDEF);
	return e;
}