aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2018-03-27 00:39:35 +0800
committerBen Hutchings <ben@decadent.org.uk>2020-03-28 21:42:54 +0000
commit2f401db12f9ab163250c0feffd5c8fe3b0d9cf38 (patch)
tree23e3d59bc4227be9bd06085363b8858c3fed905c
parenta33ea92e57007317a5c406626441029899e164e0 (diff)
downloadklibc-2f401db12f9ab163250c0feffd5c8fe3b0d9cf38.tar.gz
[klibc] dash: eval: Restore input files in evalcommand
[ dash commit 46d5a7fcea81b489819f753451c1ad2fe435f148 ] 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> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--usr/dash/eval.c3
-rw-r--r--usr/dash/input.c10
-rw-r--r--usr/dash/input.h1
3 files changed, 12 insertions, 2 deletions
diff --git a/usr/dash/eval.c b/usr/dash/eval.c
index 260554934c538..e28e56cb1eb8d 100644
--- a/usr/dash/eval.c
+++ b/usr/dash/eval.c
@@ -694,6 +694,7 @@ evalcommand(union node *cmd, int flags)
#endif
{
struct localvar_list *localvar_stop;
+ struct parsefile *file_stop;
struct redirtab *redir_stop;
struct stackmark smark;
union node *argp;
@@ -722,6 +723,7 @@ evalcommand(union node *cmd, int flags)
TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
setstackmark(&smark);
localvar_stop = pushlocalvars();
+ file_stop = parsefile;
back_exitstatus = 0;
cmdentry.cmdtype = CMDBUILTIN;
@@ -896,6 +898,7 @@ out:
if (cmd->ncmd.redirect)
popredir(execcmd);
unwindredir(redir_stop);
+ unwindfiles(file_stop);
unwindlocalvars(localvar_stop);
if (lastarg)
/* dsl: I think this is intended to be used to support
diff --git a/usr/dash/input.c b/usr/dash/input.c
index e53423c55c4b4..ae0c4c809817a 100644
--- a/usr/dash/input.c
+++ b/usr/dash/input.c
@@ -479,6 +479,13 @@ popfile(void)
}
+void unwindfiles(struct parsefile *stop)
+{
+ while (parsefile != stop)
+ popfile();
+}
+
+
/*
* Return to top level.
*/
@@ -486,8 +493,7 @@ popfile(void)
void
popallfiles(void)
{
- while (parsefile != &basepf)
- popfile();
+ unwindfiles(&basepf);
}
diff --git a/usr/dash/input.h b/usr/dash/input.h
index ec97c1d67d7c0..a9c051743b0f5 100644
--- a/usr/dash/input.h
+++ b/usr/dash/input.h
@@ -97,5 +97,6 @@ void popstring(void);
int setinputfile(const char *, int);
void setinputstring(char *);
void popfile(void);
+void unwindfiles(struct parsefile *);
void popallfiles(void);
void closescript(void);