From e5f903b9451c6e6a79eee939fcf6558a0b93cf8e Mon Sep 17 00:00:00 2001
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu, 12 Jan 2006 21:02:26 +1100
Subject: [PATCH] [EVAL] Make eval with empty arguments return 0

On Tue, Jan 10, 2006 at 10:56:23AM +0000, Gerrit Pape wrote:
> tags 347232 + patch
> quit
>
> On Mon, Jan 09, 2006 at 04:29:19PM +0100, Marco Nenciarini wrote:
> > The problem is here:
> >
> > # Set the kernel 2.6 option only for fresh install
> > test -z "$(GetMenuOpt "kopt" "")" && kopt_2_6="root=$root_device_2_6 ro"
> >
> > # Extract options for specific kernels
> > eval $(ExtractMenuOpts "\(kopt_[a-zA-Z0-9_]\+\)")
> >
> > If the first test fails and the eval argument is empty then dash
> > terminate with exitcode 1.
>
> > This is a simple testcase:
> > tm:~# bash -c "set -e ;/bin/false && : ; eval ''; echo 'END'"; echo $?
> > END
> > 0
> > tm:~# dash -c "set -e ;/bin/false && : ; eval ''; echo 'END'"; echo $?
> > 1
> >
> > if you insert any command with successfull exit status before the
> > empty eval, all work ok:
> > tm:~# bash -c "set -e ;/bin/false && : ; : ; eval ''; echo 'END'"; echo $?
> > END
> > 0
> > tm:~# dash -c "set -e ;/bin/false && : ; : ; eval ''; echo 'END'"; echo $?
> > END
> > 0
>
> Yes, I can confirm this is a bug in dash.  The standard says
>
>  EXIT STATUS
>
>      If there are no arguments, or only null arguments, eval shall
>      return a zero exit status; otherwise, it shall return the exit
>      status of the command defined by the string of concatenated
>      arguments separated by <space>s.
>
> Hi Herbert, please see http://bugs.debian.org/347232

Changed evalstring to return the exit status instead of evalskip.  This
allows us to return zero if the string is empty.
---
 ChangeLog  |    4 ++++
 src/eval.c |   18 ++++++++----------
 src/trap.c |    9 ++++-----
 3 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9f87e4e..02b966c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2006-01-12  Herbert Xu <herbert@gondor.apana.org.au>
+
+	* Fixed eval exit status with empty arguments.
+
 2005-11-26  Herbert Xu <herbert@gondor.apana.org.au>
 
 	* Release 0.5.3.
diff --git a/src/eval.c b/src/eval.c
index f8f6f0a..07e7ee2 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -150,10 +150,9 @@ evalcmd(int argc, char **argv)
                         STPUTC('\0', concat);
                         p = grabstackstr(concat);
                 }
-                evalstring(p, ~SKIPEVAL);
-                
+                return evalstring(p, ~SKIPEVAL);
         }
-        return exitstatus;
+        return 0;
 }
 
 
@@ -166,24 +165,23 @@ evalstring(char *s, int mask)
 {
 	union node *n;
 	struct stackmark smark;
-	int skip;
+	int status;
 
 	setinputstring(s);
 	setstackmark(&smark);
 
-	skip = 0;
+	status = 0;
 	while ((n = parsecmd(0)) != NEOF) {
 		evaltree(n, 0);
+		status = exitstatus;
 		popstackmark(&smark);
-		skip = evalskip;
-		if (skip)
+		if (evalskip)
 			break;
 	}
 	popfile();
 
-	skip &= mask;
-	evalskip = skip;
-	return skip;
+	evalskip &= mask;
+	return status;
 }
 
 
diff --git a/src/trap.c b/src/trap.c
index bbff81a..eae6186 100644
--- a/src/trap.c
+++ b/src/trap.c
@@ -295,7 +295,6 @@ dotrap(void)
 	char *q;
 	int i;
 	int savestatus;
-	int skip = 0;
 
 	savestatus = exitstatus;
 	pendingsigs = 0;
@@ -309,13 +308,13 @@ dotrap(void)
 		p = trap[i + 1];
 		if (!p)
 			continue;
-		skip = evalstring(p, SKIPEVAL);
+		evalstring(p, SKIPEVAL);
 		exitstatus = savestatus;
-		if (skip)
-			break;
+		if (evalskip)
+			return evalskip;
 	}
 
-	return skip;
+	return 0;
 }
 
 
-- 
1.4.3.1

