if (!comm)
return;
+ if (strcmp(k, "Close") == 0 &&
+ !comm->closed_ok) {
+ LOG("WARNING: Command %s registered for \"Close\" but not marked closed_ok",
+ comm->name);
+ }
pos = key_find(map, k);
/* cases:
LOG("End Backtrace");
}
-static int do_comm_call(struct command *comm safe,
- const struct cmd_info *ci safe)
+int do_comm_call(struct command *comm safe, const struct cmd_info *ci safe)
{
struct backtrace bt;
int ret;
+ if (ci->home->damaged & DAMAGED_DEAD)
+ return Efail;
if (times_up_fast(ci->home))
return Efail;
+ if ((ci->home->damaged & DAMAGED_CLOSED) &&
+ !comm->closed_ok)
+ return Efallthrough;
+
if (backtrace_depth > 100) {
backtrace_depth = 0;
LOG("Recursion limit of 100 reached");
}
}
-int key_lookup_prefix(struct map *m safe, const struct cmd_info *ci safe)
+int key_lookup_prefix(struct map *m safe, const struct cmd_info *ci safe,
+ bool simple)
{
+ /* A "Simple" lookup avoids the backtrace. It is used in
+ * signal handlers.
+ */
const char *k = ci->key;
int len = strlen(k);
int pos = key_find(m, k);
if (comm && comm != prev) {
((struct cmd_info*)ci)->comm = comm;
((struct cmd_info*)ci)->key = m->keys[pos+i];
- ret = do_comm_call(comm, ci);
+ if (simple)
+ ret = comm->func(ci);
+ else
+ ret = do_comm_call(comm, ci);
ASSERT(ret >= Efallthrough || ret < Eunused);
prev = comm;
/* something might have been added, recalc
while (p) {
int ret = Efallthrough;
- if (p->handle && !(p->damaged & DAMAGED_DEAD)) {
+ if (p->handle &&
+ (p->handle->closed_ok ||
+ !(p->damaged & DAMAGED_CLOSED))) {
vci->home = p;
vci->comm = p->handle;
/* Don't add this to the call stack as it
- * should simple call the desired function and
+ * should simply call the desired function and
* that will appear on the call stack.
*/
ret = p->handle->func(ci);