Fix the eval command in combination with set -e. Before this change the shell

would always terminate if eval returned with a non-zero exit status regardless
if the status was actually tested.  Unfortunately a new file-scope variable
is needed, the alternative would only be to add a new parameter to all
built-ins.

PR:	134881
This commit is contained in:
stefanf 2009-05-31 12:36:14 +00:00
parent 6fb0275352
commit 08e3c7d596
5 changed files with 11 additions and 9 deletions

View File

@ -83,6 +83,7 @@ MKINIT int evalskip; /* set if we are skipping commands */
STATIC int skipcount; /* number of levels to skip */ STATIC int skipcount; /* number of levels to skip */
MKINIT int loopnest; /* current loop nesting level */ MKINIT int loopnest; /* current loop nesting level */
int funcnest; /* depth of function calls */ int funcnest; /* depth of function calls */
STATIC int builtin_flags; /* evalcommand flags for builtins */
char *commandname; char *commandname;
@ -147,7 +148,7 @@ evalcmd(int argc, char **argv)
STPUTC('\0', concat); STPUTC('\0', concat);
p = grabstackstr(concat); p = grabstackstr(concat);
} }
evalstring(p); evalstring(p, builtin_flags & EV_TESTED);
} }
return exitstatus; return exitstatus;
} }
@ -158,7 +159,7 @@ evalcmd(int argc, char **argv)
*/ */
void void
evalstring(char *s) evalstring(char *s, int flags)
{ {
union node *n; union node *n;
struct stackmark smark; struct stackmark smark;
@ -167,7 +168,7 @@ evalstring(char *s)
setinputstring(s, 1); setinputstring(s, 1);
while ((n = parsecmd(0)) != NEOF) { while ((n = parsecmd(0)) != NEOF) {
if (n != NULL) if (n != NULL)
evaltree(n, 0); evaltree(n, flags);
popstackmark(&smark); popstackmark(&smark);
} }
popfile(); popfile();
@ -839,6 +840,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
commandname = argv[0]; commandname = argv[0];
argptr = argv + 1; argptr = argv + 1;
optptr = NULL; /* initialize nextopt */ optptr = NULL; /* initialize nextopt */
builtin_flags = flags;
exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv); exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv);
flushall(); flushall();
cmddone: cmddone:

View File

@ -46,7 +46,7 @@ struct backcmd { /* result of evalbackcmd */
}; };
int evalcmd(int, char **); int evalcmd(int, char **);
void evalstring(char *); void evalstring(char *, int);
union node; /* BLETCH for ansi C */ union node; /* BLETCH for ansi C */
void evaltree(union node *, int); void evaltree(union node *, int);
void evalbackcmd(union node *, struct backcmd *); void evalbackcmd(union node *, struct backcmd *);

View File

@ -350,7 +350,7 @@ histcmd(int argc, char **argv)
if (displayhist) { if (displayhist) {
out2str(s); out2str(s);
} }
evalstring(s); evalstring(s, 0);
if (displayhist && hist) { if (displayhist && hist) {
/* /*
* XXX what about recursive and * XXX what about recursive and
@ -382,7 +382,7 @@ histcmd(int argc, char **argv)
fclose(efp); fclose(efp);
editcmd = stalloc(strlen(editor) + strlen(editfile) + 2); editcmd = stalloc(strlen(editor) + strlen(editfile) + 2);
sprintf(editcmd, "%s %s", editor, editfile); sprintf(editcmd, "%s %s", editor, editfile);
evalstring(editcmd); /* XXX - should use no JC command */ evalstring(editcmd, 0); /* XXX - should use no JC command */
INTON; INTON;
readcmdfile(editfile); /* XXX - should read back - quick tst */ readcmdfile(editfile); /* XXX - should read back - quick tst */
unlink(editfile); unlink(editfile);

View File

@ -178,7 +178,7 @@ main(int argc, char *argv[])
state3: state3:
state = 4; state = 4;
if (minusc) { if (minusc) {
evalstring(minusc); evalstring(minusc, 0);
} }
if (sflag || minusc == NULL) { if (sflag || minusc == NULL) {
state4: /* XXX ??? - why isn't this before the "if" statement */ state4: /* XXX ??? - why isn't this before the "if" statement */

View File

@ -416,7 +416,7 @@ dotrap(void)
if (i == SIGCHLD) if (i == SIGCHLD)
ignore_sigchld++; ignore_sigchld++;
savestatus = exitstatus; savestatus = exitstatus;
evalstring(trap[i]); evalstring(trap[i], 0);
exitstatus = savestatus; exitstatus = savestatus;
if (i == SIGCHLD) if (i == SIGCHLD)
ignore_sigchld--; ignore_sigchld--;
@ -471,7 +471,7 @@ exitshell(int status)
handler = &loc1; handler = &loc1;
if ((p = trap[0]) != NULL && *p != '\0') { if ((p = trap[0]) != NULL && *p != '\0') {
trap[0] = NULL; trap[0] = NULL;
evalstring(p); evalstring(p, 0);
} }
l1: handler = &loc2; /* probably unnecessary */ l1: handler = &loc2; /* probably unnecessary */
flushall(); flushall();