aboutsummaryrefslogtreecommitdiff
path: root/bin/sh
diff options
context:
space:
mode:
authorMartin Cracauer <cracauer@FreeBSD.org>2000-08-16 10:39:43 +0000
committerMartin Cracauer <cracauer@FreeBSD.org>2000-08-16 10:39:43 +0000
commit84c3800cdcd0ca86a1c678a9eeb1adb3279550c4 (patch)
tree85d61b5f5d4aca6f3733287a2abc91d067aa3b34 /bin/sh
parent0150f3ec9b7c1f917c9322cddde710e131b5da88 (diff)
downloadsrc-84c3800cdcd0ca86a1c678a9eeb1adb3279550c4.tar.gz
src-84c3800cdcd0ca86a1c678a9eeb1adb3279550c4.zip
From submitter:
growstackblock() sometimes relocates a stack_block considered empty without properly relocating stack marks referencing that block. The first call to popstackmark() with the unrelocated stack mark as argument then causes sh to abort. Relocating the relevant stack marks seems to solve this problem. The patch changes the semantics of popstackmark() somewhat. It can only be called once after a call to setstackmark(), thus cmdloop() in main.c needs an extra call to setstackmark(). PR: bin/19983 Submitted by: Tor.Egge@fast.no Reviewed by: Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
Notes
Notes: svn path=/head/; revision=64702
Diffstat (limited to 'bin/sh')
-rw-r--r--bin/sh/main.c3
-rw-r--r--bin/sh/memalloc.c19
-rw-r--r--bin/sh/memalloc.h1
3 files changed, 22 insertions, 1 deletions
diff --git a/bin/sh/main.c b/bin/sh/main.c
index 32eb82aabf00..7d005868758f 100644
--- a/bin/sh/main.c
+++ b/bin/sh/main.c
@@ -253,12 +253,13 @@ cmdloop(top)
evaltree(n, 0);
}
popstackmark(&smark);
+ setstackmark(&smark);
if (evalskip == SKIPFILE) {
evalskip = 0;
break;
}
}
- popstackmark(&smark); /* unnecessary */
+ popstackmark(&smark);
}
diff --git a/bin/sh/memalloc.c b/bin/sh/memalloc.c
index b2155ffaa1d9..c106775254fe 100644
--- a/bin/sh/memalloc.c
+++ b/bin/sh/memalloc.c
@@ -118,6 +118,7 @@ struct stack_block {
struct stack_block stackbase;
struct stack_block *stackp = &stackbase;
+struct stackmark *markp;
char *stacknxt = stackbase.space;
int stacknleft = MINSIZE;
int sstrnleft;
@@ -176,6 +177,8 @@ setstackmark(mark)
mark->stackp = stackp;
mark->stacknxt = stacknxt;
mark->stacknleft = stacknleft;
+ mark->marknext = markp;
+ markp = mark;
}
@@ -186,6 +189,7 @@ popstackmark(mark)
struct stack_block *sp;
INTOFF;
+ markp = mark->marknext;
while (stackp != mark->stackp) {
sp = stackp;
stackp = sp->prev;
@@ -215,6 +219,7 @@ growstackblock()
char *oldspace;
int oldlen;
struct stack_block *sp;
+ struct stack_block *oldstackp;
newlen = ALIGN(stacknleft * 2 + 100);
oldspace = stacknxt;
@@ -222,6 +227,7 @@ growstackblock()
if (stacknxt == stackp->space && stackp != &stackbase) {
INTOFF;
+ oldstackp = stackp;
sp = stackp;
stackp = sp->prev;
sp = ckrealloc((pointer)sp, sizeof(struct stack_block) -
@@ -230,6 +236,19 @@ growstackblock()
stackp = sp;
stacknxt = sp->space;
stacknleft = newlen;
+ {
+ /* Stack marks pointing to the start of the old block
+ * must be relocated to point to the new block
+ */
+ struct stackmark *xmark;
+ xmark = markp;
+ while (xmark != NULL && xmark->stackp == oldstackp) {
+ xmark->stackp = stackp;
+ xmark->stacknxt = stacknxt;
+ xmark->stacknleft = stacknleft;
+ xmark = xmark->marknext;
+ }
+ }
INTON;
} else {
p = stalloc(newlen);
diff --git a/bin/sh/memalloc.h b/bin/sh/memalloc.h
index ab53a833e41a..e3ca8be83da1 100644
--- a/bin/sh/memalloc.h
+++ b/bin/sh/memalloc.h
@@ -41,6 +41,7 @@ struct stackmark {
struct stack_block *stackp;
char *stacknxt;
int stacknleft;
+ struct stackmark *marknext;
};