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.
|
||||
*/
|
||||
static void unwindfiles(struct parsefile *stop);
|
||||
static int
|
||||
isassignment(const char *p)
|
||||
{
|
||||
@ -9964,6 +9965,7 @@ evalcommand(union node *cmd, int flags)
|
||||
"\0\0", bltincmd /* why three NULs? */
|
||||
};
|
||||
struct localvar_list *localvar_stop;
|
||||
struct parsefile *file_stop;
|
||||
struct redirtab *redir_stop;
|
||||
struct stackmark smark;
|
||||
union node *argp;
|
||||
@ -9989,6 +9991,7 @@ evalcommand(union node *cmd, int flags)
|
||||
TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
|
||||
setstackmark(&smark);
|
||||
localvar_stop = pushlocalvars();
|
||||
file_stop = g_parsefile;
|
||||
back_exitstatus = 0;
|
||||
|
||||
cmdentry.cmdtype = CMDBUILTIN;
|
||||
@ -10260,6 +10263,7 @@ evalcommand(union node *cmd, int flags)
|
||||
if (cmd->ncmd.redirect)
|
||||
popredir(/*drop:*/ cmd_is_exec);
|
||||
unwindredir(redir_stop);
|
||||
unwindfiles(file_stop);
|
||||
unwindlocalvars(localvar_stop);
|
||||
if (lastarg) {
|
||||
/* dsl: I think this is intended to be used to support
|
||||
@ -10782,14 +10786,20 @@ popfile(void)
|
||||
INT_ON;
|
||||
}
|
||||
|
||||
static void
|
||||
unwindfiles(struct parsefile *stop)
|
||||
{
|
||||
while (g_parsefile != stop)
|
||||
popfile();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return to top level.
|
||||
*/
|
||||
static void
|
||||
popallfiles(void)
|
||||
{
|
||||
while (g_parsefile != &basepf)
|
||||
popfile();
|
||||
unwindfiles(&basepf);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user