On Tue, Feb 22, 2005 at 08:10:43PM +0000, Gerrit Pape wrote:
> 
> Hi Herbert, it turns out bug #268944 'sh: wrong errexit with eval'
> breaks at least one other package's postinst, raising its severity.  See

I agree with the assessment.

> below for a patch that I think fixes the problem.

I'd like to present a different fix though.  I'd prefer to keep the
set -e behaviour within the string being evaluated.  In other words,

set -e
if eval 'false; echo hi'; then :; fi

should not execute the echo statement.  Please give this patch a spin.
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
===== error.h 1.25 vs edited =====
--- 1.25/src/error.h    2004-06-29 20:55:46 +10:00
+++ edited/error.h      2005-02-23 22:15:08 +11:00
@@ -75,6 +75,7 @@
 #define EXEXEC 3       /* command execution failed */
 #define EXEXIT 4       /* exit the shell */
 #define EXSIG 5                /* trapped signal in wait(1) */
+#define EXEVAL 6       /* exit the shell due to set -e */
 
 
 /*
===== eval.c 1.99 vs edited =====
--- 1.99/src/eval.c     2004-03-07 21:46:03 +11:00
+++ edited/eval.c       2005-02-23 22:23:47 +11:00
@@ -322,8 +322,10 @@
 out:
        if (pendingsigs)
                dotrap();
-       if (flags & EV_EXIT || checkexit & exitstatus)
+       if (flags & EV_EXIT)
                exraise(EXEXIT);
+       if (checkexit & exitstatus)
+               exraise(EXEVAL);
 }
 
 
@@ -880,7 +882,7 @@
                                status = j + 128;
                        exitstatus = status;
 
-                       if (i == EXINT || spclbltin > 0) {
+                       if (i == EXINT || (i != EXEVAL && spclbltin > 0)) {
 raise:
                                longjmp(handler->loc, 1);
                        }
===== main.c 1.33 vs edited =====
--- 1.33/src/main.c     2003-10-29 21:22:45 +11:00
+++ edited/main.c       2005-02-23 22:15:02 +11:00
@@ -138,13 +138,17 @@
                        status = 2;
                        break;
 
+               case EXEXIT:
+               case EXEVAL:
+                       state = 0;
+                       /* fall through */
                default:
                        status = exitstatus;
                        break;
                }
                exitstatus = status;
 
-               if (e == EXEXIT || state == 0 || iflag == 0 || ! rootshell)
+               if (state == 0 || iflag == 0 || !rootshell)
                        exitshell();
 
                if (e == EXINT

Reply via email to