aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2006-02-05 17:10:19 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2006-02-05 17:10:19 +0000
commitda8bfb7a17bd394b54686e5991695d8c18ff3222 (patch)
tree07ae41b800dd26c747dbba55108220d9d635a05b
parent7f6a62a9bc2b98f9dad4cb1be3418b2feecccbd7 (diff)
Bug 6176 - Fix race condition
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.2@9156 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--apps/app_macro.c37
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);