diff options
author | 2013-03-24 09:54:10 +0000 | |
---|---|---|
committer | 2013-03-24 09:54:10 +0000 | |
commit | 175d36cccd2fcc2eae91dce1d3b4e3f4079aa983 (patch) | |
tree | 916aed045266a229704154541db1b8ab571a9aa2 /usr.bin/tmux/cmd-source-file.c | |
parent | Expand format variables in the run-shell and if-shell shell commands, (diff) | |
download | wireguard-openbsd-175d36cccd2fcc2eae91dce1d3b4e3f4079aa983.tar.xz wireguard-openbsd-175d36cccd2fcc2eae91dce1d3b4e3f4079aa983.zip |
Add a command queue to standardize and simplify commands that call other
commands and allow a command to block execution of subsequent
commands. This allows run-shell and if-shell to be synchronous which has
been much requested.
Each client has a default command queue and commands are consumed one at
a time from it. A command may suspend execution from the queue by
returning CMD_RETURN_WAIT and then resume it by calling cmd_continue() -
for example run-shell does this from the callback that is fired after
the job is freed.
When the command queue becomes empty, command clients are automatically
exited (unless attaching). A callback is also fired - this is used for
nested commands in, for example, if-shell which can block execution of
the client's cmdq until a new cmdq becomes empty.
Also merge all the old error/info/print functions together and lose the
old curclient/cmdclient distinction - a cmdq is bound to one client (or
none if in the configuration file), this is a command client if
c->session is NULL otherwise an attached client.
Diffstat (limited to 'usr.bin/tmux/cmd-source-file.c')
-rw-r--r-- | usr.bin/tmux/cmd-source-file.c | 86 |
1 files changed, 60 insertions, 26 deletions
diff --git a/usr.bin/tmux/cmd-source-file.c b/usr.bin/tmux/cmd-source-file.c index be6529b83ae..c4892330abb 100644 --- a/usr.bin/tmux/cmd-source-file.c +++ b/usr.bin/tmux/cmd-source-file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-source-file.c,v 1.14 2012/11/27 16:12:29 nicm Exp $ */ +/* $OpenBSD: cmd-source-file.c,v 1.15 2013/03/24 09:54:10 nicm Exp $ */ /* * Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org> @@ -26,7 +26,10 @@ * Sources a configuration file. */ -enum cmd_retval cmd_source_file_exec(struct cmd *, struct cmd_ctx *); +enum cmd_retval cmd_source_file_exec(struct cmd *, struct cmd_q *); + +void cmd_source_file_show(struct cmd_q *); +void cmd_source_file_done(struct cmd_q *); const struct cmd_entry cmd_source_file_entry = { "source-file", "source", @@ -39,35 +42,66 @@ const struct cmd_entry cmd_source_file_entry = { }; enum cmd_retval -cmd_source_file_exec(struct cmd *self, struct cmd_ctx *ctx) +cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq) +{ + struct args *args = self->args; + struct cmd_q *cmdq1; + char *cause; + + cmdq1 = cmdq_new(NULL); + cmdq1->emptyfn = cmd_source_file_done; + cmdq1->data = cmdq; + + switch (load_cfg(args->argv[0], cmdq1, &cause)) { + case -1: + if (cfg_references == 0) { + cmdq_free(cmdq1); + cmdq_error(cmdq, "%s", cause); + free(cause); + return (CMD_RETURN_ERROR); + } + ARRAY_ADD(&cfg_causes, cause); + /* FALLTHROUGH */ + case 0: + if (cfg_references == 0) + cmd_source_file_show(cmdq); + cmdq_free(cmdq1); + return (CMD_RETURN_NORMAL); + } + + cmdq->references++; + cfg_references++; + + cmdq_continue(cmdq1); + return (CMD_RETURN_WAIT); +} + +void +cmd_source_file_show(struct cmd_q *cmdq) { - struct args *args = self->args; - int retval; - u_int i; - char *cause; - - retval = load_cfg(args->argv[0], ctx, &cfg_causes); - - /* - * If the context for the cmdclient came from tmux's configuration - * file, then return the status of this command now, regardless of the - * error condition. Any errors from parsing a configuration file at - * startup will be handled for us by the server. - */ - if (cfg_references > 0 || - (ctx->curclient == NULL && ctx->cmdclient == NULL)) - return (retval); - - /* - * We were called from the command-line in which case print the errors - * gathered here directly. - */ + u_int i; + char *cause; + for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) { cause = ARRAY_ITEM(&cfg_causes, i); - ctx->print(ctx, "%s", cause); + cmdq_print(cmdq, "%s", cause); free(cause); } ARRAY_FREE(&cfg_causes); +} + +void +cmd_source_file_done(struct cmd_q *cmdq1) +{ + struct cmd_q *cmdq = cmdq1->data; + + cmdq_free(cmdq1); + + cfg_references--; + if (cmdq_free(cmdq) || cfg_references != 0) + return; + + cmd_source_file_show(cmdq); - return (retval); + cmdq_continue(cmdq); } |