diff options
author | nicm <nicm> | 2016-10-14 18:41:53 +0000 |
---|---|---|
committer | nicm <nicm> | 2016-10-14 18:41:53 +0000 |
commit | 1721d1994eb03beb8217fa3e61ed0cc097dd899e (patch) | |
tree | 43e7b2ac7cfbfee0b83cb80f59133d9ee9e65f0f /cmd-queue.c | |
parent | 0ec18e537d7f67732a789c0984bc1cb89dbb0adf (diff) | |
download | rtmux-1721d1994eb03beb8217fa3e61ed0cc097dd899e.tar.gz rtmux-1721d1994eb03beb8217fa3e61ed0cc097dd899e.tar.bz2 rtmux-1721d1994eb03beb8217fa3e61ed0cc097dd899e.zip |
source-file and some other commands can recurse back into cmdq_continue,
which could potentially free the currently running command, so we need
to take a reference to it in cmdq_continue_one.
Fixes problem reported by Theo Buehler.
Diffstat (limited to 'cmd-queue.c')
-rw-r--r-- | cmd-queue.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/cmd-queue.c b/cmd-queue.c index 8b28dd65..bafff1d6 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -55,6 +55,8 @@ cmdq_new(struct client *c) int cmdq_free(struct cmd_q *cmdq) { + log_debug("cmdq %p free: %u references", cmdq, cmdq->references); + if (--cmdq->references != 0) { if (cmdq->flags & CMD_Q_DEAD) return (1); @@ -186,6 +188,7 @@ cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist, struct mouse_event *m) static enum cmd_retval cmdq_continue_one(struct cmd_q *cmdq) { + struct cmd_list *cmdlist = cmdq->item->cmdlist; struct cmd *cmd = cmdq->cmd; enum cmd_retval retval; char *tmp; @@ -193,6 +196,8 @@ cmdq_continue_one(struct cmd_q *cmdq) const char *name; struct cmd_find_state *fsp, fs; + cmdlist->references++; + tmp = cmd_print(cmd); log_debug("cmdq %p: %s", cmdq, tmp); free(tmp); @@ -225,10 +230,12 @@ cmdq_continue_one(struct cmd_q *cmdq) end: cmdq_guard(cmdq, "end", flags); + cmd_list_free(cmdlist); return (retval); error: cmdq_guard(cmdq, "error", flags); + cmd_list_free(cmdlist); return (CMD_RETURN_ERROR); } @@ -244,8 +251,7 @@ cmdq_continue(struct cmd_q *cmdq) cmdq->references++; notify_disable(); - log_debug("continuing cmdq %p: flags %#x, client %p", cmdq, cmdq->flags, - c); + log_debug("continuing cmdq %p: flags %#x (%p)", cmdq, cmdq->flags, c); empty = TAILQ_EMPTY(&cmdq->queue); if (empty) @@ -282,6 +288,7 @@ cmdq_continue(struct cmd_q *cmdq) } while (cmdq->item != NULL); empty: + log_debug("cmdq %p empty", cmdq); if (cmdq->client_exit > 0) cmdq->client->flags |= CLIENT_EXIT; if (cmdq->emptyfn != NULL) |