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-w32-c2058ec98cf3f6722be4436cae07a386e3c7b48d.tar.gz
busybox-w32-c2058ec98cf3f6722be4436cae07a386e3c7b48d.tar.bz2
busybox-w32-c2058ec98cf3f6722be4436cae07a386e3c7b48d.zip
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)
5444 * the pipe without forking. 5444 * the pipe without forking.
5445 */ 5445 */
5446/* openhere needs this forward reference */ 5446/* openhere needs this forward reference */
5447static void expandhere(union node *arg, int fd); 5447static void expandhere(union node *arg);
5448static int 5448static int
5449openhere(union node *redir) 5449openhere(union node *redir)
5450{ 5450{
5451 char *p;
5451 int pip[2]; 5452 int pip[2];
5452 size_t len = 0; 5453 size_t len = 0;
5453 5454
5454 if (pipe(pip) < 0) 5455 if (pipe(pip) < 0)
5455 ash_msg_and_raise_perror("can't create pipe"); 5456 ash_msg_and_raise_perror("can't create pipe");
5456 if (redir->type == NHERE) { 5457
5457 len = strlen(redir->nhere.doc->narg.text); 5458 p = redir->nhere.doc->narg.text;
5458 if (len <= PIPE_BUF) { 5459 if (redir->type == NXHERE) {
5459 full_write(pip[1], redir->nhere.doc->narg.text, len); 5460 expandhere(redir->nhere.doc);
5460 goto out; 5461 p = stackblock();
5461 }
5462 } 5462 }
5463
5464 len = strlen(p);
5465 if (len <= PIPE_BUF) {
5466 xwrite(pip[1], p, len);
5467 goto out;
5468 }
5469
5463 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { 5470 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
5464 /* child */ 5471 /* child */
5465 close(pip[0]); 5472 close(pip[0]);
@@ -5468,10 +5475,7 @@ openhere(union node *redir)
5468 ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN); 5475 ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN);
5469 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN); 5476 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
5470 signal(SIGPIPE, SIG_DFL); 5477 signal(SIGPIPE, SIG_DFL);
5471 if (redir->type == NHERE) 5478 xwrite(pip[1], p, len);
5472 full_write(pip[1], redir->nhere.doc->narg.text, len);
5473 else /* NXHERE */
5474 expandhere(redir->nhere.doc, pip[1]);
5475 _exit(EXIT_SUCCESS); 5479 _exit(EXIT_SUCCESS);
5476 } 5480 }
5477 out: 5481 out:
@@ -8016,10 +8020,9 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
8016 * Expand shell variables and backquotes inside a here document. 8020 * Expand shell variables and backquotes inside a here document.
8017 */ 8021 */
8018static void 8022static void
8019expandhere(union node *arg, int fd) 8023expandhere(union node *arg)
8020{ 8024{
8021 expandarg(arg, (struct arglist *)NULL, EXP_QUOTED); 8025 expandarg(arg, (struct arglist *)NULL, EXP_QUOTED);
8022 full_write(fd, stackblock(), expdest - (char *)stackblock());
8023} 8026}
8024 8027
8025/* 8028/*
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 @@
1unset a
2cat <<EOF >/dev/null
3${a=NO}
4EOF
5echo $a BUG