aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2020-02-22 20:25:03 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2020-02-22 20:29:36 +0100
commitc2058ec98cf3f6722be4436cae07a386e3c7b48d (patch)
tree16d21416ad7716949955b73481c8224f701eb705
parentc08993f40c0c6c7bdf453e77c3aa9dae8ec0dad9 (diff)
downloadbusybox-c2058ec98cf3f6722be4436cae07a386e3c7b48d.tar.gz
ash: Expand here-documents in the current shell environment
Upstream commit: Date: Sun, 11 Nov 2007 15:27:00 +0800 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 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash.c29
-rw-r--r--shell/ash_test/ash-heredoc/heredoc_side_effects.right1
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc_side_effects.tests5
3 files changed, 22 insertions, 13 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 5fb67c0fa..01346108a 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -5444,22 +5444,29 @@ stoppedjobs(void)
* the pipe without forking.
*/
/* openhere needs this forward reference */
-static void expandhere(union node *arg, int fd);
+static void expandhere(union node *arg);
static int
openhere(union node *redir)
{
+ char *p;
int pip[2];
size_t len = 0;
if (pipe(pip) < 0)
ash_msg_and_raise_perror("can't create pipe");
- if (redir->type == NHERE) {
- len = strlen(redir->nhere.doc->narg.text);
- if (len <= PIPE_BUF) {
- full_write(pip[1], redir->nhere.doc->narg.text, len);
- goto out;
- }
+
+ p = redir->nhere.doc->narg.text;
+ if (redir->type == NXHERE) {
+ expandhere(redir->nhere.doc);
+ p = stackblock();
}
+
+ len = strlen(p);
+ if (len <= PIPE_BUF) {
+ xwrite(pip[1], p, len);
+ goto out;
+ }
+
if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
/* child */
close(pip[0]);
@@ -5468,10 +5475,7 @@ openhere(union node *redir)
ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN);
ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
signal(SIGPIPE, SIG_DFL);
- if (redir->type == NHERE)
- full_write(pip[1], redir->nhere.doc->narg.text, len);
- else /* NXHERE */
- expandhere(redir->nhere.doc, pip[1]);
+ xwrite(pip[1], p, len);
_exit(EXIT_SUCCESS);
}
out:
@@ -8016,10 +8020,9 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
* Expand shell variables and backquotes inside a here document.
*/
static void
-expandhere(union node *arg, int fd)
+expandhere(union node *arg)
{
expandarg(arg, (struct arglist *)NULL, EXP_QUOTED);
- full_write(fd, stackblock(), expdest - (char *)stackblock());
}
/*
diff --git a/shell/ash_test/ash-heredoc/heredoc_side_effects.right b/shell/ash_test/ash-heredoc/heredoc_side_effects.right
new file mode 100644
index 000000000..53b2c03c1
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc_side_effects.right
@@ -0,0 +1 @@
+NO BUG
diff --git a/shell/ash_test/ash-heredoc/heredoc_side_effects.tests b/shell/ash_test/ash-heredoc/heredoc_side_effects.tests
new file mode 100755
index 000000000..3fb622ae4
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc_side_effects.tests
@@ -0,0 +1,5 @@
+unset a
+cat <<EOF >/dev/null
+${a=NO}
+EOF
+echo $a BUG