summary refs log tree commit diff
diff options
context:
space:
mode:
authorherbert <herbert@gondor.apana.org.au>2005-03-28 20:28:01 +1000
committerHerbert Xu <herbert@gondor.apana.org.au>2005-09-26 18:33:05 +1000
commit71d448c29c85afd16a4feb68b23fde6c8cf02875 (patch)
tree2414dda91f580f2c124522b41c244f0eb528acfa
parentRemoved unnecessary inclusion of eval.h from parser.c. (diff)
downloaddash-71d448c29c85afd16a4feb68b23fde6c8cf02875.tar.gz
dash-71d448c29c85afd16a4feb68b23fde6c8cf02875.zip
Added eflag fixes for trap and minusc.
Let evaltree handle traps from cmdloop.
Reset evalskip after minusc is executed.
Stop executing traps once SKIPEVAL is seen.
Diffstat (limited to '')
-rw-r--r--ChangeLog3
-rw-r--r--src/eval.c31
-rw-r--r--src/eval.h2
-rw-r--r--src/histedit.c6
-rw-r--r--src/main.c2
-rw-r--r--src/trap.c27
-rw-r--r--src/trap.h2
7 files changed, 49 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index a6ba252..a01503a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,9 @@
 	* Generalise setinputfile for use in read_profile/readcmdfile.
 	* Handle SKIPEVAL in read_profile by exiting.
 	* Let evaltree handle traps from cmdloop.
+	* Reset evalskip after minusc is executed.
+	* Stop executing traps once SKIPEVAL is seen.
+	* Only handle each signal once in dotrap.
 
 2005-03-25  Gerrit Pape <pape@smarden.org>
 
diff --git a/src/eval.c b/src/eval.c
index 31272da..ac4425c 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -163,7 +163,8 @@ evalcmd(int argc, char **argv)
                         STPUTC('\0', concat);
                         p = grabstackstr(concat);
                 }
-                evalstring(p);
+                evalstring(p, ~SKIPEVAL);
+                
         }
         return exitstatus;
 }
@@ -173,23 +174,29 @@ evalcmd(int argc, char **argv)
  * Execute a command or commands contained in a string.
  */
 
-void
-evalstring(char *s)
+int
+evalstring(char *s, int mask)
 {
 	union node *n;
 	struct stackmark smark;
+	int skip;
 
-	setstackmark(&smark);
 	setinputstring(s);
+	setstackmark(&smark);
 
+	skip = 0;
 	while ((n = parsecmd(0)) != NEOF) {
 		evaltree(n, 0);
 		popstackmark(&smark);
-		if (evalskip)
+		skip = evalskip;
+		if (skip)
 			break;
 	}
 	popfile();
-	popstackmark(&smark);
+
+	skip &= mask;
+	evalskip = skip;
+	return skip;
 }
 
 
@@ -319,12 +326,15 @@ setstatus:
 		break;
 	}
 out:
-	if (pendingsigs)
-		dotrap();
-	if (flags & EV_EXIT)
-		exraise(EXEXIT);
 	if ((checkexit & exitstatus))
 		evalskip |= SKIPEVAL;
+	else if (pendingsigs && dotrap())
+		goto exexit;
+
+	if (flags & EV_EXIT) {
+exexit:
+		exraise(EXEXIT);
+	}
 }
 
 
@@ -930,7 +940,6 @@ cmddone:
 	commandname = savecmdname;
 	exsig = 0;
 	handler = savehandler;
-	evalskip &= ~SKIPEVAL;
 
 	return i;
 }
diff --git a/src/eval.h b/src/eval.h
index 3d0a9a6..bd2cee0 100644
--- a/src/eval.h
+++ b/src/eval.h
@@ -51,7 +51,7 @@ struct backcmd {		/* result of evalbackcmd */
 	struct job *jp;		/* job structure for command */
 };
 
-void evalstring(char *);
+int evalstring(char *, int);
 union node;	/* BLETCH for ansi C */
 void evaltree(union node *, int);
 void evalbackcmd(union node *, struct backcmd *);
diff --git a/src/histedit.c b/src/histedit.c
index 0d435cd..9c5656b 100644
--- a/src/histedit.c
+++ b/src/histedit.c
@@ -383,7 +383,8 @@ histcmd(int argc, char **argv)
 					out2str(s);
 				}
 
-				evalstring(strcpy(stalloc(strlen(s) + 1), s));
+				evalstring(strcpy(stalloc(strlen(s) + 1), s),
+					   ~0);
 				if (displayhist && hist) {
 					/*
 					 *  XXX what about recursive and
@@ -407,7 +408,8 @@ histcmd(int argc, char **argv)
 		fclose(efp);
 		editcmd = stalloc(strlen(editor) + strlen(editfile) + 2);
 		sprintf(editcmd, "%s %s", editor, editfile);
-		evalstring(editcmd, 0);	/* XXX - should use no JC command */
+		/* XXX - should use no JC command */
+		evalstring(editcmd, ~0);
 		INTON;
 		readcmdfile(editfile);	/* XXX - should read back - quick tst */
 		unlink(editfile);
diff --git a/src/main.c b/src/main.c
index fd13ab2..317447c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -189,7 +189,7 @@ state2:
 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/src/trap.c b/src/trap.c
index 15ff49a..6264b5c 100644
--- a/src/trap.c
+++ b/src/trap.c
@@ -301,23 +301,34 @@ onsig(int signo)
  * handlers while we are executing a trap handler.
  */
 
-void
+int
 dotrap(void)
 {
 	char *p;
 	char *q;
+	int i;
 	int savestatus;
+	int skip = 0;
 
 	savestatus = exitstatus;
-	q = gotsig;
-	while (pendingsigs = 0, barrier(), (p = memchr(q, 1, NSIG - 1))) {
-		*p = 0;
-		p = trap[p - q + 1];
+	pendingsigs = 0;
+	barrier();
+
+	for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) {
+		if (!*q)
+			continue;
+		*q = 0;
+
+		p = trap[i + 1];
 		if (!p)
 			continue;
-		evalstring(p);
+		skip = evalstring(p, SKIPEVAL);
 		exitstatus = savestatus;
+		if (skip)
+			break;
 	}
+
+	return skip;
 }
 
 
@@ -364,9 +375,9 @@ exitshell(void)
 		goto out;
 	}
 	handler = &loc;
-	if ((p = trap[0]) != NULL && *p != '\0') {
+	if ((p = trap[0])) {
 		trap[0] = NULL;
-		evalstring(p);
+		evalstring(p, 0);
 	}
 	flushall();
 out:
diff --git a/src/trap.h b/src/trap.h
index fd164a8..380651b 100644
--- a/src/trap.h
+++ b/src/trap.h
@@ -49,7 +49,7 @@ void clear_traps(void);
 void setsignal(int);
 void ignoresig(int);
 void onsig(int);
-void dotrap(void);
+int dotrap(void);
 void setinteractive(int);
 void exitshell(void) __attribute__((__noreturn__));
 int decode_signal(const char *, int);