From 25caeb903be133e723d5cfe4894cc7fbf732802f Mon Sep 17 00:00:00 2001 From: "Steffen (Daode) Nurpmeso" Date: Thu, 12 Jun 2014 18:21:22 +0200 Subject: [PATCH] `localopts': handle recursive macro calls.. After a long server hang during a recursive macro call and multiple manual interrupts i got a `localopts' crash ... when calling the macro again. Reproducable via set header define t0 { call t1 #var t1 t2 t3 } define t1 { localopts 1 set hold noheader t1 echo t1.in call t2 echo t1.out #var t1 t2 t3 } define t2 { echo t2.in set t2 call t3 echo t2.out } define t3 { echo t3.in set t3 # debug command: called kill(getpid(), SIGINT) du # ok: !kill -INT $$ echo t3.out } # ... ? ~t0 ? ~t0 Beside not dealing with recursion our temporary_localopts_store hack (which tries to circumvent that the signal-manager is yet not implemented) also did not do _localopts=NULL, which was the actual cause of the crash since temporary_localopts_store uses that value, so the dangling thing of before the interruption will survive. --- acmava.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/acmava.c b/acmava.c index 38b99e97..55f80c39 100644 --- a/acmava.c +++ b/acmava.c @@ -554,12 +554,17 @@ _ma_exec(struct macro const *mp, struct var **unroller) for (lp = mp->ma_contents; lp; lp = lp->l_next) { var_clear_allow_undefined = TRU1; memcpy(buf, lp->l_line, lp->l_length +1); - temporary_localopts_store = _localopts; /* XXX intermediate hack */ - /* FIXME if the execute() jumps away (via INT) then our internal state - * FIXME is messed up, even though temporary_localopts_free() is likely - * FIXME to correct some of that */ - rv |= execute(buf, 0, lp->l_length); /* XXX break if != 0 ? */ - temporary_localopts_store = NULL; /* XXX intermediate hack */ + { + struct _n2 { + struct _n2 *up; + struct lostack *lo; + } *x = salloc(sizeof *x); /* FIXME intermediate hack (signal man+) */ + x->up = temporary_localopts_store; + x->lo = _localopts; + temporary_localopts_store = x; + rv |= execute(buf, 0, lp->l_length); /* XXX break if != 0 ? */ + temporary_localopts_store = x->up; /* FIXME intermediate hack */ + } var_clear_allow_undefined = FAL0; } ac_free(buf); @@ -1271,13 +1276,22 @@ jleave: FL void temporary_localopts_free(void) /* XXX intermediate hack */ { - struct lostack *losp; + struct _n2 { + struct _n2 *up; + struct lostack *lo; + } *x; NYD_ENTER; var_clear_allow_undefined = FAL0; - losp = temporary_localopts_store; + x = temporary_localopts_store; temporary_localopts_store = NULL; - _localopts_unroll(&losp->s_localopts); + _localopts = NULL; + + while (x != NULL) { + struct lostack *losp = x->lo; + x = x->up; + _localopts_unroll(&losp->s_localopts); + } NYD_LEAVE; } -- 2.11.4.GIT