ash: eval: Restore input files in evalcommand
Upstream commit: Date: Tue, 27 Mar 2018 00:39:35 +0800 eval: Restore input files in evalcommand When evalcommand invokes a command that modifies parsefile and then bails out without popping the file, we need to ensure the input file is restored so that the shell can continue to execute. Reported-by: Martijn Dekker <martijn@inlv.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> function old new delta unwindfiles - 20 +20 evalcommand 1635 1653 +18 getoptscmd 584 595 +11 popallfiles 20 10 -10 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 2/1 up/down: 49/-10) Total: 39 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
58eb805c2c
commit
1c5eb88cd8
14
shell/ash.c
14
shell/ash.c
@ -9942,6 +9942,7 @@ find_builtin(const char *name)
|
|||||||
/*
|
/*
|
||||||
* Execute a simple command.
|
* Execute a simple command.
|
||||||
*/
|
*/
|
||||||
|
static void unwindfiles(struct parsefile *stop);
|
||||||
static int
|
static int
|
||||||
isassignment(const char *p)
|
isassignment(const char *p)
|
||||||
{
|
{
|
||||||
@ -9964,6 +9965,7 @@ evalcommand(union node *cmd, int flags)
|
|||||||
"\0\0", bltincmd /* why three NULs? */
|
"\0\0", bltincmd /* why three NULs? */
|
||||||
};
|
};
|
||||||
struct localvar_list *localvar_stop;
|
struct localvar_list *localvar_stop;
|
||||||
|
struct parsefile *file_stop;
|
||||||
struct redirtab *redir_stop;
|
struct redirtab *redir_stop;
|
||||||
struct stackmark smark;
|
struct stackmark smark;
|
||||||
union node *argp;
|
union node *argp;
|
||||||
@ -9989,6 +9991,7 @@ evalcommand(union node *cmd, int flags)
|
|||||||
TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
|
TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
|
||||||
setstackmark(&smark);
|
setstackmark(&smark);
|
||||||
localvar_stop = pushlocalvars();
|
localvar_stop = pushlocalvars();
|
||||||
|
file_stop = g_parsefile;
|
||||||
back_exitstatus = 0;
|
back_exitstatus = 0;
|
||||||
|
|
||||||
cmdentry.cmdtype = CMDBUILTIN;
|
cmdentry.cmdtype = CMDBUILTIN;
|
||||||
@ -10260,6 +10263,7 @@ evalcommand(union node *cmd, int flags)
|
|||||||
if (cmd->ncmd.redirect)
|
if (cmd->ncmd.redirect)
|
||||||
popredir(/*drop:*/ cmd_is_exec);
|
popredir(/*drop:*/ cmd_is_exec);
|
||||||
unwindredir(redir_stop);
|
unwindredir(redir_stop);
|
||||||
|
unwindfiles(file_stop);
|
||||||
unwindlocalvars(localvar_stop);
|
unwindlocalvars(localvar_stop);
|
||||||
if (lastarg) {
|
if (lastarg) {
|
||||||
/* dsl: I think this is intended to be used to support
|
/* dsl: I think this is intended to be used to support
|
||||||
@ -10782,14 +10786,20 @@ popfile(void)
|
|||||||
INT_ON;
|
INT_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
unwindfiles(struct parsefile *stop)
|
||||||
|
{
|
||||||
|
while (g_parsefile != stop)
|
||||||
|
popfile();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return to top level.
|
* Return to top level.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
popallfiles(void)
|
popallfiles(void)
|
||||||
{
|
{
|
||||||
while (g_parsefile != &basepf)
|
unwindfiles(&basepf);
|
||||||
popfile();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user