diff --git a/cmd-invoke.c b/cmd-invoke.c index f2be5884e..c7872706c 100644 --- a/cmd-invoke.c +++ b/cmd-invoke.c @@ -61,8 +61,9 @@ static int cmd_invoke_assignment(struct cmdq_item *, struct cmd_invoke_state *, struct cmd_parse_node *); static int cmd_invoke_if(struct cmdq_item *, struct cmd_invoke_state *, struct cmd_parse_node *); -static struct cmd *cmd_invoke_build_command(struct cmdq_item *, - struct cmd_invoke_state *, struct cmd_parse_node *); +static struct cmd *cmd_invoke_build_command(struct cmdq_item *, + struct cmd_invoke_state *, struct cmd_parse_node *); +static int cmd_invoke_read_only(struct cmdq_item *, struct cmd *); /* Push a node's child range onto the traversal stack. */ static void @@ -365,6 +366,20 @@ fail: return (NULL); } +static int +cmd_invoke_read_only(struct cmdq_item *item, struct cmd *cmd) +{ + struct client *c = cmdq_get_client(item); + const struct cmd_entry *entry = cmd_get_entry(cmd); + + if (c == NULL || (~c->flags & CLIENT_READONLY)) + return (0); + if (entry->flags & CMD_READONLY) + return (0); + cmdq_error(item, "client is read-only"); + return (-1); +} + /* Create the first invoke queue item for a parsed tree. */ struct cmdq_item * cmd_invoke_get(struct cmd_parse_tree *tree, struct cmdq_state *state, @@ -487,6 +502,11 @@ cmd_invoke_fire(struct cmdq_item *item, struct cmd_invoke_state *is) cmd_invoke_skip_sequence(is); break; } + if (cmd_invoke_read_only(item, cmd) != 0) { + cmd_free(cmd); + cmd_invoke_skip_sequence(is); + break; + } /* * Queue one command followed by this walker. WAIT and diff --git a/key-bindings.c b/key-bindings.c index b2d10416b..ae3eac05e 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -688,41 +688,21 @@ key_bindings_init(void) cmdq_append(NULL, cmdq_get_callback(key_bindings_init_done, NULL)); } -static enum cmd_retval -key_bindings_read_only(struct cmdq_item *item, __unused void *data) -{ - cmdq_error(item, "client is read-only"); - return (CMD_RETURN_ERROR); -} - struct cmdq_item * key_bindings_dispatch(struct key_binding *bd, struct cmdq_item *item, struct client *c, struct key_event *event, struct cmd_find_state *fs) { struct cmdq_item *new_item; struct cmdq_state *new_state; - int readonly, flags = 0; + int flags = 0; - if (c == NULL || (~c->flags & CLIENT_READONLY)) - readonly = 1; - else { -#if 0 /* XXX: command parser conversion */ - readonly = cmd_list_all_have(bd->cmdlist, CMD_READONLY); -#else - readonly = 0; -#endif - } + if (bd->flags & KEY_BINDING_REPEAT) + flags |= CMDQ_STATE_REPEAT; + new_state = cmdq_new_state(fs, event, flags); - if (!readonly) - new_item = cmdq_get_callback(key_bindings_read_only, NULL); - else { - if (bd->flags & KEY_BINDING_REPEAT) - flags |= CMDQ_STATE_REPEAT; - new_state = cmdq_new_state(fs, event, flags); + new_item = cmd_invoke_get(bd->cmd, new_state, NULL); + cmdq_free_state(new_state); - new_item = cmd_invoke_get(bd->cmd, new_state, NULL); - cmdq_free_state(new_state); - } if (item != NULL) new_item = cmdq_insert_after(item, new_item); else