<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/19531">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span></span><br></pre><div style="white-space:pre-wrap">Approvals:
Joshua Colp: Looks good to me, but someone else must approve
George Joseph: Looks good to me, approved
Friendly Automation: Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">app_stack: Print proper exit location for PBXless channels.<br><br>When gosub is executed on channels without a PBX, the context,<br>extension, and priority are initialized to the channel driver's<br>default location for that endpoint. As a result, the last Return<br>will restore this location and the Gosub logs will print out bogus<br>information about our exit point.<br><br>To fix this, on channels that don't have a PBX, the execution<br>location is left intact on the last return if there are no<br>further stack frames left. This allows the correct location<br>to be printed out to the user, rather than the bogus default<br>context.<br><br>ASTERISK-30076 #close<br><br>Change-Id: I1d42a99c9aa9e3708d32718863175158a894e414<br>(cherry picked from commit 12d18b0a40381eb90145e352bf144a71f8dd2555)<br>---<br>M apps/app_stack.c<br>1 file changed, 64 insertions(+), 8 deletions(-)<br><br></pre>
<pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/apps/app_stack.c b/apps/app_stack.c</span><br><span>index a84a45c..70aff6f 100644</span><br><span>--- a/apps/app_stack.c</span><br><span>+++ b/apps/app_stack.c</span><br><span>@@ -377,6 +377,26 @@</span><br><span> return res;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int frames_left(struct ast_channel *chan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_datastore *stack_store;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gosub_stack_list *oldlist;</span><br><span style="color: hsl(120, 100%, 40%);">+ int exists;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_lock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ stack_store = ast_channel_datastore_find(chan, &stack_info, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!stack_store) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_unlock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ oldlist = stack_store->data;</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_LOCK(oldlist);</span><br><span style="color: hsl(120, 100%, 40%);">+ exists = oldlist->first ? 1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_LIST_UNLOCK(oldlist);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_unlock(chan);</span><br><span style="color: hsl(120, 100%, 40%);">+ return exists;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int return_exec(struct ast_channel *chan, const char *data)</span><br><span> {</span><br><span> struct ast_datastore *stack_store;</span><br><span>@@ -384,6 +404,7 @@</span><br><span> struct gosub_stack_list *oldlist;</span><br><span> const char *retval = data;</span><br><span> int res = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int lastframe;</span><br><span> </span><br><span> ast_channel_lock(chan);</span><br><span> if (!(stack_store = ast_channel_datastore_find(chan, &stack_info, NULL))) {</span><br><span>@@ -395,6 +416,7 @@</span><br><span> oldlist = stack_store->data;</span><br><span> AST_LIST_LOCK(oldlist);</span><br><span> oldframe = AST_LIST_REMOVE_HEAD(oldlist, entries);</span><br><span style="color: hsl(120, 100%, 40%);">+ lastframe = oldlist->first ? 0 : 1;</span><br><span> AST_LIST_UNLOCK(oldlist);</span><br><span> </span><br><span> if (!oldframe) {</span><br><span>@@ -412,12 +434,19 @@</span><br><span> * what was there before. Channels that do not have a PBX may</span><br><span> * not have the context or exten set.</span><br><span> */</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_context_set(chan, oldframe->context);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_exten_set(chan, oldframe->extension);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP)) {</span><br><span style="color: hsl(0, 100%, 40%);">- --oldframe->priority;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_channel_pbx(chan) || !lastframe) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* If there's no PBX, the "old location" is simply</span><br><span style="color: hsl(120, 100%, 40%);">+ * the configured context for the device, such as</span><br><span style="color: hsl(120, 100%, 40%);">+ * for pre-dial handlers, and restoring this location</span><br><span style="color: hsl(120, 100%, 40%);">+ * is nonsensical. So if no PBX and there are no further</span><br><span style="color: hsl(120, 100%, 40%);">+ * frames, leave the location as it is. */</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_context_set(chan, oldframe->context);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_exten_set(chan, oldframe->extension);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ --oldframe->priority;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_channel_priority_set(chan, oldframe->priority);</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_priority_set(chan, oldframe->priority);</span><br><span> ast_set2_flag(ast_channel_flags(chan), oldframe->in_subroutine, AST_FLAG_SUBROUTINE_EXEC);</span><br><span> </span><br><span> gosub_release_frame(chan, oldframe);</span><br><span>@@ -1068,10 +1097,13 @@</span><br><span> ast_channel_priority(chan), ast_channel_name(chan));</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- /* Did the routine return? */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_channel_priority(chan) == saved_priority</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Did the routine return?</span><br><span style="color: hsl(120, 100%, 40%);">+ * For things like predial where there's no PBX on the channel yet,</span><br><span style="color: hsl(120, 100%, 40%);">+ * the last return leaves the location alone so we can print it out correctly here.</span><br><span style="color: hsl(120, 100%, 40%);">+ * So to ensure we finished properly, make sure there are no frames left in that case. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((!ast_channel_pbx(chan) && !frames_left(chan)) || (ast_channel_priority(chan) == saved_priority</span><br><span> && !strcmp(ast_channel_context(chan), saved_context)</span><br><span style="color: hsl(0, 100%, 40%);">- && !strcmp(ast_channel_exten(chan), saved_exten)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ && !strcmp(ast_channel_exten(chan), saved_exten))) {</span><br><span> ast_verb(3, "%s Internal %s(%s) complete GOSUB_RETVAL=%s\n",</span><br><span> ast_channel_name(chan), app_gosub, sub_args,</span><br><span> S_OR(pbx_builtin_getvar_helper(chan, "GOSUB_RETVAL"), ""));</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/19531">change 19531</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/19531"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 18 </div>
<div style="display:none"> Gerrit-Change-Id: I1d42a99c9aa9e3708d32718863175158a894e414 </div>
<div style="display:none"> Gerrit-Change-Number: 19531 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: N A <asterisk@phreaknet.org> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>