From 08e3c7d596923f5022fda6ee58d6e7ac15e65edb Mon Sep 17 00:00:00 2001 From: stefanf Date: Sun, 31 May 2009 12:36:14 +0000 Subject: [PATCH] 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 --- bin/sh/eval.c | 8 +++++--- bin/sh/eval.h | 2 +- bin/sh/histedit.c | 4 ++-- bin/sh/main.c | 2 +- bin/sh/trap.c | 4 ++-- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 26e21489440f..e00a94a82b85 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -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: diff --git a/bin/sh/eval.h b/bin/sh/eval.h index 01c914acf880..11f74702ab20 100644 --- a/bin/sh/eval.h +++ b/bin/sh/eval.h @@ -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 *); diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c index 0bea2b8a37c8..5698a8f9c5db 100644 --- a/bin/sh/histedit.c +++ b/bin/sh/histedit.c @@ -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); diff --git a/bin/sh/main.c b/bin/sh/main.c index e77ff4e1a95d..77526b569ea1 100644 --- a/bin/sh/main.c +++ b/bin/sh/main.c @@ -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 */ diff --git a/bin/sh/trap.c b/bin/sh/trap.c index 16ef0aab6fe1..099dc11bec6e 100644 --- a/bin/sh/trap.c +++ b/bin/sh/trap.c @@ -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();