summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/builtins.def.in3
-rw-r--r--src/eval.c26
-rw-r--r--src/histedit.c4
-rw-r--r--src/mkbuiltins3
-rw-r--r--src/trap.c3
5 files changed, 23 insertions, 16 deletions
diff --git a/src/builtins.def.in b/src/builtins.def.in
index 362ff3f..266d0ec 100644
--- a/src/builtins.def.in
+++ b/src/builtins.def.in
@@ -40,6 +40,7 @@
  * The -a flag specifies that this is a posix 'assignment builtin' command.
  * The -s flag specifies that this is a posix 'special builtin' command.
  * The -u flag specifies that this is a posix 'standard utility'.
+ * The -n flag specifies that this command has a special entry point.
  * The rest of the line specifies the command name or names used to run
  * the command.
  */
@@ -62,7 +63,7 @@ cdcmd		-u cd chdir
 commandcmd	-u command
 dotcmd		-s .
 echocmd		echo
-evalcmd		-s eval
+evalcmd		-ns eval
 execcmd		-s exec
 exitcmd		-s exit
 exportcmd	-as export -as readonly
diff --git a/src/eval.c b/src/eval.c
index b90a354..66c2209 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -97,7 +97,7 @@ STATIC void evalcommand(union node *, int, struct backcmd *);
 #else
 STATIC void evalcommand(union node *, int);
 #endif
-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 eprintlist(struct output *, struct strlist *, int);
@@ -129,8 +129,7 @@ RESET {
  * The eval commmand.
  */
 
-int
-evalcmd(int argc, char **argv)
+static int evalcmd(int argc, char **argv, int flags)
 {
         char *p;
         char *concat;
@@ -150,7 +149,7 @@ evalcmd(int argc, char **argv)
                         STPUTC('\0', concat);
                         p = grabstackstr(concat);
                 }
-                return evalstring(p, ~SKIPEVAL);
+                return evalstring(p, flags & EV_TESTED);
         }
         return 0;
 }
@@ -161,7 +160,7 @@ evalcmd(int argc, char **argv)
  */
 
 int
-evalstring(char *s, int mask)
+evalstring(char *s, int flags)
 {
 	union node *n;
 	struct stackmark smark;
@@ -172,7 +171,7 @@ evalstring(char *s, int mask)
 
 	status = 0;
 	while ((n = parsecmd(0)) != NEOF) {
-		evaltree(n, 0);
+		evaltree(n, flags);
 		status = exitstatus;
 		popstackmark(&smark);
 		if (evalskip)
@@ -180,7 +179,6 @@ evalstring(char *s, int mask)
 	}
 	popfile();
 
-	evalskip &= mask;
 	return status;
 }
 
@@ -861,7 +859,7 @@ bail:
 			}
 			listsetvar(list, i);
 		}
-		if (evalbltin(cmdentry.u.cmd, argc, argv)) {
+		if (evalbltin(cmdentry.u.cmd, argc, argv, flags)) {
 			int status;
 			int i;
 
@@ -899,10 +897,12 @@ out:
 }
 
 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;
 	struct jmploc jmploc;
+	int status;
 	int i;
 
 	savecmdname = commandname;
@@ -913,10 +913,14 @@ evalbltin(const struct builtincmd *cmd, int argc, char **argv) {
 	commandname = argv[0];
 	argptr = argv + 1;
 	optptr = NULL;			/* initialize nextopt */
-	exitstatus = (*cmd->builtin)(argc, argv);
+	if (cmd == EVALCMD)
+		status = evalcmd(argc, argv, flags);
+	else
+		status = (*cmd->builtin)(argc, argv);
 	flushall();
+	status |= outerr(out1);
+	exitstatus = status;
 cmddone:
-	exitstatus |= outerr(out1);
 	freestdout();
 	commandname = savecmdname;
 	handler = savehandler;
diff --git a/src/histedit.c b/src/histedit.c
index 36d7937..9a1e533 100644
--- a/src/histedit.c
+++ b/src/histedit.c
@@ -371,7 +371,7 @@ histcmd(int argc, char **argv)
 				}
 
 				evalstring(strcpy(stalloc(strlen(s) + 1), s),
-					   ~0);
+					   0);
 				if (displayhist && hist) {
 					/*
 					 *  XXX what about recursive and
@@ -396,7 +396,7 @@ histcmd(int argc, char **argv)
 		editcmd = stalloc(strlen(editor) + strlen(editfile) + 2);
 		sprintf(editcmd, "%s %s", editor, editfile);
 		/* XXX - should use no JC command */
-		evalstring(editcmd, ~0);
+		evalstring(editcmd, 0);
 		INTON;
 		readcmdfile(editfile);	/* XXX - should read back - quick tst */
 		unlink(editfile);
diff --git a/src/mkbuiltins b/src/mkbuiltins
index 424d59a..977edb4 100644
--- a/src/mkbuiltins
+++ b/src/mkbuiltins
@@ -71,7 +71,8 @@ awk '{	for (i = 2 ; i <= NF ; i++) {
 			opt = substr($2, 2)
 			$2 = $3
 		}
-		printf "\t{ \"%s\", %s, %d },\n", $1, $2,
+		printf "\t{ \"%s\", %s, %d },\n", $1,
+			(opt ~ /n/) ? "NULL" : $2,
 			(opt ~ /s/) + (opt ~ /[su]/) * 2 + (opt ~ /a/) * 4
 	}'
 echo '};'
diff --git a/src/trap.c b/src/trap.c
index 5b8b046..16703b3 100644
--- a/src/trap.c
+++ b/src/trap.c
@@ -310,7 +310,7 @@ dotrap(void)
 		p = trap[i + 1];
 		if (!p)
 			continue;
-		evalstring(p, SKIPEVAL);
+		evalstring(p, 0);
 		exitstatus = savestatus;
 		if (evalskip)
 			return evalskip;
@@ -365,6 +365,7 @@ exitshell(void)
 	handler = &loc;
 	if ((p = trap[0])) {
 		trap[0] = NULL;
+		evalskip = 0;
 		evalstring(p, 0);
 	}
 out: