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; };