summary refs log tree commit diff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-11-11 15:27:00 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2007-11-11 15:27:00 +0800
commitf4ee8c859c3d3fe6c5b540bffa6a0b6f320f8b3e (patch)
tree22b3d58db0458f6e4c03a30422c4708dc0e2ff7e
parent[EXPAND] Removed herefd hack (diff)
downloaddash-f4ee8c859c3d3fe6c5b540bffa6a0b6f320f8b3e.tar.gz
dash-f4ee8c859c3d3fe6c5b540bffa6a0b6f320f8b3e.zip
[EXPAND] Expand here-documents in the current shell environment
Previously we always expanded here-documents in a subshell.  This is
contrary to the POSIX specification and how other shells behave.  What's
more this slows down many expansions due to the extra fork (however, it
must be said that it is possible for it speed up certain expansions by
running it simultaneously with the command on two CPUs).

This patch move the expansion into the current shell environment.

Test case:

	unset a
	cat <<- EOF > /dev/null
		${a=NOT}
	EOF
	echo ${a}BAD

Old result:

	BAD

New result:

	NOTBAD
-rw-r--r--ChangeLog1
-rw-r--r--src/expand.c12
-rw-r--r--src/expand.h1
-rw-r--r--src/redir.c24
4 files changed, 15 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index 39940b9..de37261 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,7 @@
 
 	* Removed noexpand/length check on eofmark.
 	* Removed herefd hack.
+	* Expand here-documents in the current shell environment.
 
 2007-10-20  Herbert Xu <herbert@gondor.apana.org.au>
 
diff --git a/src/expand.c b/src/expand.c
index ee699e8..f3d63c4 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -178,18 +178,6 @@ static inline const char *getpwhome(const char *name)
 
 
 /*
- * Expand shell variables and backquotes inside a here document.
- */
-
-void
-expandhere(union node *arg, int fd)
-{
-	expandarg(arg, (struct arglist *)NULL, EXP_QUOTED);
-	xwrite(fd, stackblock(), expdest - (char *)stackblock());
-}
-
-
-/*
  * Perform variable substitution and command substitution on an argument,
  * placing the resulting list of arguments in arglist.  If EXP_FULL is true,
  * perform splitting and file name expansion.  When arglist is NULL, perform
diff --git a/src/expand.h b/src/expand.h
index 225b004..1862aea 100644
--- a/src/expand.h
+++ b/src/expand.h
@@ -62,7 +62,6 @@ struct arglist {
 
 
 union node;
-void expandhere(union node *, int);
 void expandarg(union node *, struct arglist *, int);
 void expari(int);
 #define rmescapes(p) _rmescapes((p), 0)
diff --git a/src/redir.c b/src/redir.c
index 33dbc88..ce34db0 100644
--- a/src/redir.c
+++ b/src/redir.c
@@ -295,18 +295,25 @@ err:
 STATIC int
 openhere(union node *redir)
 {
+	char *p;
 	int pip[2];
 	size_t len = 0;
 
 	if (pipe(pip) < 0)
 		sh_error("Pipe call failed");
-	if (redir->type == NHERE) {
-		len = strlen(redir->nhere.doc->narg.text);
-		if (len <= PIPESIZE) {
-			xwrite(pip[1], redir->nhere.doc->narg.text, len);
-			goto out;
-		}
+
+	p = redir->nhere.doc->narg.text;
+	if (redir->type == NXHERE) {
+		expandarg(redir->nhere.doc, NULL, EXP_QUOTED);
+		p = stackblock();
+	}
+
+	len = strlen(p);
+	if (len <= PIPESIZE) {
+		xwrite(pip[1], p, len);
+		goto out;
 	}
+
 	if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
 		close(pip[0]);
 		signal(SIGINT, SIG_IGN);
@@ -316,10 +323,7 @@ openhere(union node *redir)
 		signal(SIGTSTP, SIG_IGN);
 #endif
 		signal(SIGPIPE, SIG_DFL);
-		if (redir->type == NHERE)
-			xwrite(pip[1], redir->nhere.doc->narg.text, len);
-		else
-			expandhere(redir->nhere.doc, pip[1]);
+		xwrite(pip[1], p, len);
 		_exit(0);
 	}
 out: