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 */
|
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:
|
||||||
|
@ -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 *);
|
||||||
|
@ -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);
|
||||||
|
@ -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 */
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user