summary refs log tree commit diff
path: root/src/eval.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2011-07-07 13:58:48 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2011-07-07 16:41:14 +0800
commitee5cbe9fd6bc02f31b4d955606288de36c3d4eab (patch)
tree618418c1b268fdd17e98e09d7a6f96c3dcc86b66 /src/eval.c
parent[EVAL] Remove unused EV_BACKCMD flag (diff)
downloaddash-ee5cbe9fd6bc02f31b4d955606288de36c3d4eab.tar.gz
dash-ee5cbe9fd6bc02f31b4d955606288de36c3d4eab.zip
[SHELL] Optimize dash -c "command" to avoid a fork
On Sun, Apr 10, 2011 at 07:36:49AM +0000, Jonathan Nieder wrote:
> From: Jilles Tjoelker <jilles@stack.nl>
> Date: Sat, 13 Jun 2009 16:17:45 -0500
> 
> This change only affects strings passed to -c, when the -s option is
> not used.
> 
> Use the EV_EXIT flag to inform the eval machinery that the string
> being passed is the entirety of input.  This way, a fork may be
> omitted in many special cases.
> 
> If there are empty lines after the last command, the evalcmd will not
> see the end early enough and forks will not be omitted. The same thing
> seems to happen in bash.
> 
> Example:
>   sh -c 'ps lT'
> No longer shows a shell process waiting for ps to finish.
> 
> [jn: ported from FreeBSD SVN r194128.  Bugs are mine.]
> 
> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>

Instead of detecting EOF using the input layer, I'm going to
use the parser instead.  In either case, we always have to read
ahead in order to complete the parsing of the previous node.
Therefore we always know whether there is more to come, except
in the case where we see a newline/semicolon or similar.

For the purposes of sh -c, this should be sufficient.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to '')
-rw-r--r--src/eval.c6
1 files changed, 1 insertions, 5 deletions
diff --git a/src/eval.c b/src/eval.c
index 86423b4..6e7b932 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -65,10 +65,6 @@
 #endif
 
 
-/* flags in argument to evaltree */
-#define EV_EXIT 01		/* exit after evaluating tree */
-#define EV_TESTED 02		/* exit status is checked; ignore -e flag */
-
 int evalskip;			/* set if we are skipping commands */
 STATIC int skipcount;		/* number of levels to skip */
 MKINIT int loopnest;		/* current loop nesting level */
@@ -169,7 +165,7 @@ evalstring(char *s, int flags)
 
 	status = 0;
 	while ((n = parsecmd(0)) != NEOF) {
-		evaltree(n, flags);
+		evaltree(n, flags & ~(parser_eof() ? 0 : EV_EXIT));
 		status = exitstatus;
 		popstackmark(&smark);
 		if (evalskip)
ubject'>Customize cgit CSSJune McEnroe 2019-12-18Use :target rather than :focus pseudo-classJune McEnroe :target persists after you click on something else. 2019-12-18Copy cgit auxiliary binaries properlyJune McEnroe 2019-12-18Add git.causal.agency cgit configJune McEnroe 2019-12-18Bail from hi if input is binaryJune McEnroe NULs in the input cause an infinite loop in htmlEscape, not to mention regexes obviously not working, etc. 2019-12-16Post "cgit setup"June McEnroe