summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--src/error.h1
-rw-r--r--src/eval.c10
-rw-r--r--src/main.c6
4 files changed, 15 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 1734ecf..97598ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 2005-02-25  Herbert Xu <herbert@gondor.apana.org.au>
 
 	* Changed boolean rootshell into shlvl counter.
+	* Catch set -e exits within built-in commands.
 
 2005-01-31  Gerrit Pape <pape@smarden.org>
 
diff --git a/src/error.h b/src/error.h
index c8e1a2e..2db9fe6 100644
--- a/src/error.h
+++ b/src/error.h
@@ -75,6 +75,7 @@ extern int exerrno;	/* error for EXEXEC */
 #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 */
 
 
 /*
diff --git a/src/eval.c b/src/eval.c
index d1bf317..f7f0aeb 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -73,6 +73,7 @@ __RCSID("$NetBSD: eval.c,v 1.71 2003/01/23 03:33:16 rafal Exp $");
 #include "error.h"
 #include "show.h"
 #include "mystring.h"
+#include "main.h"
 #ifndef SMALL
 #include "myhistedit.h"
 #endif
@@ -322,8 +323,10 @@ setstatus:
 out:
 	if (pendingsigs)
 		dotrap();
-	if (flags & EV_EXIT || checkexit & exitstatus)
+	if (flags & EV_EXIT)
 		exraise(EXEXIT);
+	if (checkexit & exitstatus)
+		exraise(EXEVAL);
 }
 
 
@@ -708,12 +711,14 @@ evalcommand(union node *cmd, int flags)
 	int spclbltin;
 	int execcmd;
 	int status;
+	int oldlvl;
 	char **nargv;
 
 	/* First expand the arguments. */
 	TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
 	setstackmark(&smark);
 	back_exitstatus = 0;
+	oldlvl = shlvl;
 
 	cmdentry.cmdtype = CMDBUILTIN;
 	cmdentry.u.cmd = &bltin;
@@ -880,7 +885,8 @@ bail:
 				status = j + 128;
 			exitstatus = status;
 
-			if (i == EXINT || spclbltin > 0) {
+			if (i == EXINT || (i != EXEVAL && spclbltin > 0) ||
+			    oldlvl != shlvl) {
 raise:
 				longjmp(handler->loc, 1);
 			}
diff --git a/src/main.c b/src/main.c
index 0d69e4f..4902cfa 100644
--- a/src/main.c
+++ b/src/main.c
@@ -138,13 +138,17 @@ main(int argc, char **argv)
 			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 || shlvl)
 			exitshell();
 
 		if (e == EXINT