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:
parent
6fb0275352
commit
08e3c7d596
@ -83,6 +83,7 @@ MKINIT int evalskip; /* set if we are skipping commands */
|
||||
STATIC int skipcount; /* number of levels to skip */
|
||||
MKINIT int loopnest; /* current loop nesting level */
|
||||
int funcnest; /* depth of function calls */
|
||||
STATIC int builtin_flags; /* evalcommand flags for builtins */
|
||||
|
||||
|
||||
char *commandname;
|
||||
@ -147,7 +148,7 @@ evalcmd(int argc, char **argv)
|
||||
STPUTC('\0', concat);
|
||||
p = grabstackstr(concat);
|
||||
}
|
||||
evalstring(p);
|
||||
evalstring(p, builtin_flags & EV_TESTED);
|
||||
}
|
||||
return exitstatus;
|
||||
}
|
||||
@ -158,7 +159,7 @@ evalcmd(int argc, char **argv)
|
||||
*/
|
||||
|
||||
void
|
||||
evalstring(char *s)
|
||||
evalstring(char *s, int flags)
|
||||
{
|
||||
union node *n;
|
||||
struct stackmark smark;
|
||||
@ -167,7 +168,7 @@ evalstring(char *s)
|
||||
setinputstring(s, 1);
|
||||
while ((n = parsecmd(0)) != NEOF) {
|
||||
if (n != NULL)
|
||||
evaltree(n, 0);
|
||||
evaltree(n, flags);
|
||||
popstackmark(&smark);
|
||||
}
|
||||
popfile();
|
||||
@ -839,6 +840,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
|
||||
commandname = argv[0];
|
||||
argptr = argv + 1;
|
||||
optptr = NULL; /* initialize nextopt */
|
||||
builtin_flags = flags;
|
||||
exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv);
|
||||
flushall();
|
||||
cmddone:
|
||||
|
@ -46,7 +46,7 @@ struct backcmd { /* result of evalbackcmd */
|
||||
};
|
||||
|
||||
int evalcmd(int, char **);
|
||||
void evalstring(char *);
|
||||
void evalstring(char *, int);
|
||||
union node; /* BLETCH for ansi C */
|
||||
void evaltree(union node *, int);
|
||||
void evalbackcmd(union node *, struct backcmd *);
|
||||
|
@ -350,7 +350,7 @@ histcmd(int argc, char **argv)
|
||||
if (displayhist) {
|
||||
out2str(s);
|
||||
}
|
||||
evalstring(s);
|
||||
evalstring(s, 0);
|
||||
if (displayhist && hist) {
|
||||
/*
|
||||
* XXX what about recursive and
|
||||
@ -382,7 +382,7 @@ histcmd(int argc, char **argv)
|
||||
fclose(efp);
|
||||
editcmd = stalloc(strlen(editor) + strlen(editfile) + 2);
|
||||
sprintf(editcmd, "%s %s", editor, editfile);
|
||||
evalstring(editcmd); /* XXX - should use no JC command */
|
||||
evalstring(editcmd, 0); /* XXX - should use no JC command */
|
||||
INTON;
|
||||
readcmdfile(editfile); /* XXX - should read back - quick tst */
|
||||
unlink(editfile);
|
||||
|
@ -178,7 +178,7 @@ main(int argc, char *argv[])
|
||||
state3:
|
||||
state = 4;
|
||||
if (minusc) {
|
||||
evalstring(minusc);
|
||||
evalstring(minusc, 0);
|
||||
}
|
||||
if (sflag || minusc == NULL) {
|
||||
state4: /* XXX ??? - why isn't this before the "if" statement */
|
||||
|
@ -416,7 +416,7 @@ dotrap(void)
|
||||
if (i == SIGCHLD)
|
||||
ignore_sigchld++;
|
||||
savestatus = exitstatus;
|
||||
evalstring(trap[i]);
|
||||
evalstring(trap[i], 0);
|
||||
exitstatus = savestatus;
|
||||
if (i == SIGCHLD)
|
||||
ignore_sigchld--;
|
||||
@ -471,7 +471,7 @@ exitshell(int status)
|
||||
handler = &loc1;
|
||||
if ((p = trap[0]) != NULL && *p != '\0') {
|
||||
trap[0] = NULL;
|
||||
evalstring(p);
|
||||
evalstring(p, 0);
|
||||
}
|
||||
l1: handler = &loc2; /* probably unnecessary */
|
||||
flushall();
|
||||
|
Loading…
Reference in New Issue
Block a user