.name = "function",
.debug_name = "function",
.actions = {
+ /*
+ * By default, functions don't change the section rcode.
+ * We can't make generalisations about what the intent
+ * of the function callbacks are, so isntead of having
+ * implicit, confusing behaviour, we always discard the
+ * rcode UNLESS the function explicitly sets it.
+ */
.actions = {
- [RLM_MODULE_REJECT] = 0,
- [RLM_MODULE_FAIL] = 0,
- [RLM_MODULE_OK] = 0,
- [RLM_MODULE_HANDLED] = 0,
- [RLM_MODULE_INVALID] = 0,
- [RLM_MODULE_DISALLOW] = 0,
- [RLM_MODULE_NOTFOUND] = 0,
- [RLM_MODULE_NOOP] = 0,
- [RLM_MODULE_UPDATED] = 0
+ [RLM_MODULE_REJECT] = MOD_ACTION_NOT_SET,
+ [RLM_MODULE_FAIL] = MOD_ACTION_NOT_SET,
+ [RLM_MODULE_OK] = MOD_ACTION_NOT_SET,
+ [RLM_MODULE_HANDLED] = MOD_ACTION_NOT_SET,
+ [RLM_MODULE_INVALID] = MOD_ACTION_NOT_SET,
+ [RLM_MODULE_DISALLOW] = MOD_ACTION_NOT_SET,
+ [RLM_MODULE_NOTFOUND] = MOD_ACTION_NOT_SET,
+ [RLM_MODULE_NOOP] = MOD_ACTION_NOT_SET,
+ [RLM_MODULE_UPDATED] = MOD_ACTION_NOT_SET,
+ [RLM_MODULE_TIMEOUT] = MOD_ACTION_NOT_SET
},
.retry = RETRY_INIT,
}
* These can be pushed by any other type of unlang op to allow a submodule or function
* deeper in the C call stack to establish a new resumption point.
*
- * @param[in] _reuslt_p Where to write the result.
+ * @note If you're pushing a function onto the stack to resume execution in a module, you're probably
+ * doing it wrong. Use unlang_module_yield() instead, and change the process function for the
+ * module.
+ *
+ * @note By default the rcodes from functions will be discarded. This can be altered on a per-function
+ * basis by the func or repeat functions setting result_p->priority to a non-zero value.
+ * Results can also be collected by passing in a non-NULL _result_p pointer.
+ * You may disagree with this behaviour, but you're wrong.
+ *
+ * @param[in] _result_p Where to write the result.
* @param[in] _request The current request.
* @param[in] _func to call going up the stack.
* @param[in] _repeat function to call going back down the stack (may be NULL).
* This is the field that's evaluated in unlang conditions
* like `if (ok)`.
*/
- if (frame->instruction && is_rcode_set(frame) && (request->rcode != result->rcode)) {
- RDEBUG3("Setting request->rcode to '%s'",
- fr_table_str_by_value(rcode_table, result->rcode, "<INVALID>"));
- request->rcode = result->rcode;
- }
+ if (frame->instruction) {
+ if (is_rcode_set(frame) && (request->rcode != result->rcode)) {
+ RDEBUG3("Setting request->rcode to '%s'",
+ fr_table_str_by_value(rcode_table, result->rcode, "<INVALID>"));
+ request->rcode = result->rcode;
+ }
- /*
- * The array holds a default priority for this return
- * code. Grab it in preference to any unset priority.
- */
- if (result->priority == MOD_ACTION_NOT_SET) {
- result->priority = instruction->actions.actions[result->rcode];
+ /*
+ * The array holds a default priority for this return
+ * code. Grab it in preference to any unset priority.
+ */
+ if (result->priority == MOD_ACTION_NOT_SET) {
+ result->priority = instruction->actions.actions[result->rcode];
- RDEBUG4("** [%i] %s - using default instruction priority for %s, %d",
- stack->depth, __FUNCTION__,
- fr_table_str_by_value(mod_rcode_table, result->rcode, "<invalid>"),
- result->priority);
+ RDEBUG4("** [%i] %s - using default instruction priority for %s, %d",
+ stack->depth, __FUNCTION__,
+ fr_table_str_by_value(mod_rcode_table, result->rcode, "<invalid>"),
+ result->priority);
+ }
}
/*