static int loopnest; /* current loop nesting level */
/* Forward decl way out to parsing code - dotrap needs it */
-static int evalstring(char *s, int mask);
+static int evalstring(char *s, int flags);
/* Called to execute a trap.
* Single callsite - at the end of evaltree().
*g = 0;
if (!t)
continue;
- evalstring(t, SKIPEVAL);
+ evalstring(t, 0);
exitstatus = savestatus;
if (evalskip) {
TRACE(("dotrap returns %d\n", evalskip));
static void expredir(union node *);
static int evalpipe(union node *, int);
static int evalcommand(union node *, int);
-static int evalbltin(const struct builtincmd *, int, char **);
+static int evalbltin(const struct builtincmd *, int, char **, int);
static void prehash(union node *);
/*
/* Forward declarations for builtintab[] */
static int breakcmd(int, char **) FAST_FUNC;
static int dotcmd(int, char **) FAST_FUNC;
-static int evalcmd(int, char **) FAST_FUNC;
+static int evalcmd(int, char **, int) FAST_FUNC;
static int exitcmd(int, char **) FAST_FUNC;
static int exportcmd(int, char **) FAST_FUNC;
#if ENABLE_ASH_GETOPTS
#if ENABLE_ASH_BUILTIN_ECHO
{ BUILTIN_REGULAR "echo" , echocmd },
#endif
- { BUILTIN_SPEC_REG "eval" , evalcmd },
+ { BUILTIN_SPEC_REG "eval" , NULL }, /*evalcmd() has a differing prototype*/
{ BUILTIN_SPEC_REG "exec" , execcmd },
{ BUILTIN_SPEC_REG "exit" , exitcmd },
{ BUILTIN_SPEC_REG_ASSG "export" , exportcmd },
* to reap the zombie and make kill detect that it's gone: */
dowait(DOWAIT_NONBLOCK, NULL);
- if (evalbltin(cmdentry.u.cmd, argc, argv)) {
+ if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) {
int exit_status;
int i = exception_type;
if (i == EXEXIT || i == EXEXEC)
}
static int
-evalbltin(const struct builtincmd *cmd, int argc, char **argv)
+evalbltin(const struct builtincmd *cmd, int argc, char **argv, int flags)
{
char *volatile savecmdname;
struct jmploc *volatile savehandler;
struct jmploc jmploc;
+ int status;
int i;
savecmdname = commandname;
commandname = argv[0];
argptr = argv + 1;
optptr = NULL; /* initialize nextopt */
- exitstatus = (*cmd->builtin)(argc, argv);
+ if (cmd == EVALCMD)
+ status = evalcmd(argc, argv, flags);
+ else
+ status = (*cmd->builtin)(argc, argv);
flush_stdout_stderr();
+ status |= ferror(stdout);
+ exitstatus = status;
cmddone:
- exitstatus |= ferror(stdout);
clearerr(stdout);
commandname = savecmdname;
exception_handler = savehandler;
* Execute a command or commands contained in a string.
*/
static int
-evalstring(char *s, int mask)
+evalstring(char *s, int flags)
{
union node *n;
struct stackmark smark;
while ((n = parsecmd(0)) != NODE_EOF) {
int i;
- i = evaltree(n, 0);
+ i = evaltree(n, flags);
if (n)
status = i;
popstackmark(&smark);
popfile();
stunalloc(s);
- evalskip &= mask;
return status;
}
* The eval command.
*/
static int FAST_FUNC
-evalcmd(int argc UNUSED_PARAM, char **argv)
+evalcmd(int argc UNUSED_PARAM, char **argv, int flags)
{
char *p;
char *concat;
STPUTC('\0', concat);
p = grabstackstr(concat);
}
- return evalstring(p, ~SKIPEVAL);
+ return evalstring(p, flags & EV_TESTED);
}
return 0;
}
p = trap[0];
if (p) {
trap[0] = NULL;
+ evalskip = 0;
evalstring(p, 0);
free(p);
}