diff options
Diffstat (limited to 'server-client.c')
-rw-r--r-- | server-client.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/server-client.c b/server-client.c index 5697e343..83202a47 100644 --- a/server-client.c +++ b/server-client.c @@ -124,8 +124,7 @@ server_client_create(int fd) c->fd = -1; c->cwd = NULL; - c->cmdq = cmdq_new(c); - c->cmdq->client_exit = 1; + TAILQ_INIT(&c->queue); c->stdin_data = evbuffer_new(); c->stdout_data = evbuffer_new(); @@ -242,10 +241,6 @@ server_client_lost(struct client *c) free(c->prompt_string); free(c->prompt_buffer); - c->cmdq->flags |= CMD_Q_DEAD; - cmdq_free(c->cmdq); - c->cmdq = NULL; - environ_free(c->environ); proc_remove_peer(c->peer); @@ -279,6 +274,9 @@ server_client_free(__unused int fd, __unused short events, void *arg) log_debug("free client %p (%d references)", c, c->references); + if (!TAILQ_EMPTY(&c->queue)) + fatalx("queue not empty"); + if (c->references == 0) free(c); } @@ -1262,6 +1260,29 @@ server_client_dispatch(struct imsg *imsg, void *arg) } } +/* Callback when command is done. */ +static enum cmd_retval +server_client_command_done(struct cmd_q *cmdq, __unused void *data) +{ + struct client *c = cmdq->client; + + if (~c->flags & CLIENT_ATTACHED) + c->flags |= CLIENT_EXIT; + return (CMD_RETURN_NORMAL); +} + +/* Show an error message. */ +static enum cmd_retval +server_client_command_error(struct cmd_q *cmdq, void *data) +{ + char *error = data; + + cmdq_error(cmdq, "%s", error); + free(error); + + return (CMD_RETURN_NORMAL); +} + /* Handle command message. */ static void server_client_dispatch_command(struct client *c, struct imsg *imsg) @@ -1284,7 +1305,7 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg) argc = data.argc; if (cmd_unpack_argv(buf, len, argc, &argv) != 0) { - cmdq_error(c->cmdq, "command too long"); + cause = xstrdup("command too long"); goto error; } @@ -1295,20 +1316,19 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg) } if ((cmdlist = cmd_list_parse(argc, argv, NULL, 0, &cause)) == NULL) { - cmdq_error(c->cmdq, "%s", cause); cmd_free_argv(argc, argv); goto error; } cmd_free_argv(argc, argv); - if (c != cfg_client || cfg_finished) - cmdq_run(c->cmdq, cmdlist, NULL); - else - cmdq_append(c->cmdq, cmdlist, NULL); + cmdq_append(c, cmdq_get_command(cmdlist, NULL, NULL, 0)); + cmdq_append(c, cmdq_get_callback(server_client_command_done, NULL)); cmd_list_free(cmdlist); return; error: + cmdq_append(c, cmdq_get_callback(server_client_command_error, cause)); + if (cmdlist != NULL) cmd_list_free(cmdlist); |