[git commit] ash: Expand here-documents in the current shell environment
Denys Vlasenko
vda.linux at googlemail.com
Sat Feb 22 19:29:36 UTC 2020
commit: https://git.busybox.net/busybox/commit/?id=c2058ec98cf3f6722be4436cae07a386e3c7b48d
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master
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 at googlemail.com>
---
shell/ash.c | 29 ++++++++++++----------
.../ash-heredoc/heredoc_side_effects.right | 1 +
.../ash-heredoc/heredoc_side_effects.tests | 5 ++++
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
More information about the busybox-cvs
mailing list