On Wed, Jun 22, 2005 at 02:15:22PM -0400, Joey Hess wrote: > [EMAIL PROTECTED]:~>cat test > set -e > eval false || true > exit 0 > [EMAIL PROTECTED]:~>busybox sh test > zsh: exit 1 busybox sh test > [EMAIL PROTECTED]:~>sh test > [EMAIL PROTECTED]:~>dash test > [EMAIL PROTECTED]:~>bash test > [EMAIL PROTECTED]:~>zsh test > [EMAIL PROTECTED]:~> > > Workarond is to enclose the eval statement in parens, so this will work in > debootstrap: > > (eval $(eval echo \${EXIT_THING_$n})) 2>/dev/null || true > > Cloning the bug to busybox, I'm using 1.00 in the test above, though > busybox-cvs must also have the bug.
This is a rather hacky patch against busybox-cvs (but should apply to busybox without too much trouble) for this. Unfortunately I had to take the approach of avoiding throwing the exception in the first place, necessitating a static variable, rather than catching the exception in evalbltin() if flags & EV_TESTED, which I think would have been much neater. However, when I tried to take the latter approach, I apparently didn't manage to restore all the pre-exception state properly or something, because immediately after evaluating 'eval false || true' the (interactive) shell decided it had hit EOF on input and exited. Somebody who understands busybox ash better might want to look into this. I also haven't run this through a shell test suite to make sure I didn't break anything else. That really needs to happen before applying this to the Debian package. diff -u busybox-cvs-20040623/shell/ash.c busybox-cvs-20040623/shell/ash.c --- busybox-cvs-20040623/shell/ash.c +++ busybox-cvs-20040623/shell/ash.c @@ -1218,7 +1218,7 @@ -static void evalstring(char *); +static void evalstring(char *, int); union node; /* BLETCH for ansi C */ static void evaltree(union node *, int); static void evalbackcmd(union node *, struct backcmd *); @@ -1229,6 +1229,8 @@ static int skipcount; /* number of levels to skip */ static int funcnest; /* depth of function calls */ +static int bltintested = 0; /* builtin command tested; appease set -e */ + /* reasons for skipping commands (see comment on breakcmd routine) */ #define SKIPBREAK 1 #define SKIPCONT 2 @@ -2692,7 +2694,7 @@ static void expredir(union node *); static void evalpipe(union node *, int); static void evalcommand(union node *, int); -static int evalbltin(const struct builtincmd *, int, char **); +static int evalbltin(const struct builtincmd *, int, char **, int); static int evalfun(struct funcnode *, int, char **, int); static void prehash(union node *); static int bltincmd(int, char **); @@ -2732,7 +2734,7 @@ STPUTC('\0', concat); p = grabstackstr(concat); } - evalstring(p); + evalstring(p, bltintested ? EV_TESTED : 0); } return exitstatus; } @@ -2743,7 +2745,7 @@ */ static void -evalstring(char *s) +evalstring(char *s, int flags) { union node *n; struct stackmark smark; @@ -2752,7 +2754,7 @@ setinputstring(s); while ((n = parsecmd(0)) != NEOF) { - evaltree(n, 0); + evaltree(n, flags); popstackmark(&smark); if (evalskip) break; @@ -3387,7 +3389,7 @@ } listsetvar(list, i); } - if (evalbltin(cmdentry.u.cmd, argc, argv)) { + if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) { int exit_status; int i, j; @@ -3432,9 +3434,10 @@ } 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; + volatile int savebltintested; struct jmploc jmploc; int i; @@ -3446,10 +3449,14 @@ commandname = argv[0]; argptr = argv + 1; optptr = NULL; /* initialize nextopt */ + savebltintested = bltintested; + if (flags & EV_TESTED) + bltintested = 1; exitstatus = (*cmd->builtin)(argc, argv); flushall(); cmddone: exitstatus |= ferror(stdout); + bltintested = savebltintested; commandname = savecmdname; exsig = 0; handler = savehandler; @@ -7966,7 +7973,7 @@ state3: state = 4; if (minusc) - evalstring(minusc); + evalstring(minusc, 0); if (sflag || minusc == NULL) { #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY @@ -11817,7 +11824,7 @@ p = trap[p - q + 1]; if (!p) continue; - evalstring(p); + evalstring(p, 0); exitstatus = savestatus; } } @@ -11910,7 +11917,7 @@ handler = &loc; if ((p = trap[0]) != NULL && *p != '\0') { trap[0] = NULL; - evalstring(p); + evalstring(p, 0); } flushall(); #ifdef CONFIG_FEATURE_COMMAND_SAVEHISTORY -- Colin Watson [EMAIL PROTECTED] -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]