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>
This commit is contained in:
parent
c08993f40c
commit
c2058ec98c
25
shell/ash.c
25
shell/ash.c
@ -5444,22 +5444,29 @@ stoppedjobs(void)
|
|||||||
* the pipe without forking.
|
* the pipe without forking.
|
||||||
*/
|
*/
|
||||||
/* openhere needs this forward reference */
|
/* openhere needs this forward reference */
|
||||||
static void expandhere(union node *arg, int fd);
|
static void expandhere(union node *arg);
|
||||||
static int
|
static int
|
||||||
openhere(union node *redir)
|
openhere(union node *redir)
|
||||||
{
|
{
|
||||||
|
char *p;
|
||||||
int pip[2];
|
int pip[2];
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
if (pipe(pip) < 0)
|
if (pipe(pip) < 0)
|
||||||
ash_msg_and_raise_perror("can't create pipe");
|
ash_msg_and_raise_perror("can't create pipe");
|
||||||
if (redir->type == NHERE) {
|
|
||||||
len = strlen(redir->nhere.doc->narg.text);
|
p = redir->nhere.doc->narg.text;
|
||||||
|
if (redir->type == NXHERE) {
|
||||||
|
expandhere(redir->nhere.doc);
|
||||||
|
p = stackblock();
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(p);
|
||||||
if (len <= PIPE_BUF) {
|
if (len <= PIPE_BUF) {
|
||||||
full_write(pip[1], redir->nhere.doc->narg.text, len);
|
xwrite(pip[1], p, len);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
|
if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
|
||||||
/* child */
|
/* child */
|
||||||
close(pip[0]);
|
close(pip[0]);
|
||||||
@ -5468,10 +5475,7 @@ openhere(union node *redir)
|
|||||||
ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN);
|
ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN);
|
||||||
ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
|
ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
|
||||||
signal(SIGPIPE, SIG_DFL);
|
signal(SIGPIPE, SIG_DFL);
|
||||||
if (redir->type == NHERE)
|
xwrite(pip[1], p, len);
|
||||||
full_write(pip[1], redir->nhere.doc->narg.text, len);
|
|
||||||
else /* NXHERE */
|
|
||||||
expandhere(redir->nhere.doc, pip[1]);
|
|
||||||
_exit(EXIT_SUCCESS);
|
_exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
@ -8016,10 +8020,9 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
|
|||||||
* Expand shell variables and backquotes inside a here document.
|
* Expand shell variables and backquotes inside a here document.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
expandhere(union node *arg, int fd)
|
expandhere(union node *arg)
|
||||||
{
|
{
|
||||||
expandarg(arg, (struct arglist *)NULL, EXP_QUOTED);
|
expandarg(arg, (struct arglist *)NULL, EXP_QUOTED);
|
||||||
full_write(fd, stackblock(), expdest - (char *)stackblock());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
1
shell/ash_test/ash-heredoc/heredoc_side_effects.right
Normal file
1
shell/ash_test/ash-heredoc/heredoc_side_effects.right
Normal file
@ -0,0 +1 @@
|
|||||||
|
NO BUG
|
5
shell/ash_test/ash-heredoc/heredoc_side_effects.tests
Executable file
5
shell/ash_test/ash-heredoc/heredoc_side_effects.tests
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
unset a
|
||||||
|
cat <<EOF >/dev/null
|
||||||
|
${a=NO}
|
||||||
|
EOF
|
||||||
|
echo $a BUG
|
Loading…
Reference in New Issue
Block a user