diff options
author | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-02-05 17:10:19 +0000 |
---|---|---|
committer | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-02-05 17:10:19 +0000 |
commit | da8bfb7a17bd394b54686e5991695d8c18ff3222 (patch) | |
tree | 07ae41b800dd26c747dbba55108220d9d635a05b /apps/app_macro.c | |
parent | 7f6a62a9bc2b98f9dad4cb1be3418b2feecccbd7 (diff) |
Bug 6176 - Fix race condition
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@9156 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_macro.c')
-rw-r--r-- | apps/app_macro.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/apps/app_macro.c b/apps/app_macro.c index 72b75777c..7e7c9141a 100644 --- a/apps/app_macro.c +++ b/apps/app_macro.c @@ -104,7 +104,7 @@ static int macro_exec(struct ast_channel *chan, void *data) char *offsets; int offset, depth; int setmacrocontext=0; - int autoloopflag; + int autoloopflag, dead = 0; char *save_macro_exten; char *save_macro_context; @@ -216,8 +216,8 @@ static int macro_exec(struct ast_channel *chan, void *data) break; } switch(res) { - case MACRO_EXIT_RESULT: - res = 0; + case MACRO_EXIT_RESULT: + res = 0; goto out; case AST_PBX_KEEPALIVE: if (option_debug) @@ -231,6 +231,7 @@ static int macro_exec(struct ast_channel *chan, void *data) ast_log(LOG_DEBUG, "Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro); else if (option_verbose > 1) ast_verbose( VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s'\n", chan->context, chan->exten, chan->priority, chan->name, macro); + dead = 1; goto out; } } @@ -250,37 +251,44 @@ static int macro_exec(struct ast_channel *chan, void *data) out: /* Reset the depth back to what it was when the routine was entered (like if we called Macro recursively) */ snprintf(depthc, sizeof(depthc), "%d", depth); - pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); + if (!dead) { + pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc); + + ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP); + } - ast_set2_flag(chan, autoloopflag, AST_FLAG_IN_AUTOLOOP); - for (x=1; x<argc; x++) { + for (x = 1; x < argc; x++) { /* Restore old arguments and delete ours */ snprintf(varname, sizeof(varname), "ARG%d", x); if (oldargs[x]) { - pbx_builtin_setvar_helper(chan, varname, oldargs[x]); + if (!dead) + pbx_builtin_setvar_helper(chan, varname, oldargs[x]); free(oldargs[x]); - } else { + } else if (!dead) { pbx_builtin_setvar_helper(chan, varname, NULL); } } /* Restore macro variables */ - pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten); + if (!dead) { + pbx_builtin_setvar_helper(chan, "MACRO_EXTEN", save_macro_exten); + pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context); + pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority); + } if (save_macro_exten) free(save_macro_exten); - pbx_builtin_setvar_helper(chan, "MACRO_CONTEXT", save_macro_context); if (save_macro_context) free(save_macro_context); - pbx_builtin_setvar_helper(chan, "MACRO_PRIORITY", save_macro_priority); if (save_macro_priority) free(save_macro_priority); - if (setmacrocontext) { + + if (!dead && setmacrocontext) { chan->macrocontext[0] = '\0'; chan->macroexten[0] = '\0'; chan->macropriority = 0; } - if (!strcasecmp(chan->context, fullmacro)) { + if (!dead && !strcasecmp(chan->context, fullmacro)) { /* If we're leaving the macro normally, restore original information */ chan->priority = oldpriority; ast_copy_string(chan->context, oldcontext, sizeof(chan->context)); @@ -299,7 +307,8 @@ static int macro_exec(struct ast_channel *chan, void *data) } } - pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset); + if (!dead) + pbx_builtin_setvar_helper(chan, "MACRO_OFFSET", save_macro_offset); if (save_macro_offset) free(save_macro_offset); LOCAL_USER_REMOVE(u); |