From d1e6ce26722e3a0774d240e39bbc69b07e93c48b Mon Sep 17 00:00:00 2001 From: Nicholas Marriott <nicm@openbsd.org> Date: Fri, 22 Mar 2013 15:49:55 +0000 Subject: [PATCH] Add functions to allocate and free command contexts rather than doing it all on the stack. --- cmd-if-shell.c | 20 +++++++------------- cmd-list.c | 5 +++-- cmd-run-shell.c | 22 ++++++++-------------- cmd.c | 46 +++++++++++++++++++++++++++++++++------------- 4 files changed, 51 insertions(+), 42 deletions(-) diff --git a/cmd-if-shell.c b/cmd-if-shell.c index 4cb9de82..ab69e8b5 100644 --- a/cmd-if-shell.c +++ b/cmd-if-shell.c @@ -47,7 +47,7 @@ const struct cmd_entry cmd_if_shell_entry = { struct cmd_if_shell_data { char *cmd_if; char *cmd_else; - struct cmd_ctx ctx; + struct cmd_ctx *ctx; }; enum cmd_retval @@ -63,12 +63,9 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx) cdata->cmd_else = xstrdup(args->argv[2]); else cdata->cmd_else = NULL; - memcpy(&cdata->ctx, ctx, sizeof cdata->ctx); - if (ctx->cmdclient != NULL) - ctx->cmdclient->references++; - if (ctx->curclient != NULL) - ctx->curclient->references++; + cdata->ctx = ctx; + cmd_ref_ctx(ctx); job_run(shellcmd, cmd_if_shell_callback, cmd_if_shell_free, cdata); @@ -79,7 +76,7 @@ void cmd_if_shell_callback(struct job *job) { struct cmd_if_shell_data *cdata = job->data; - struct cmd_ctx *ctx = &cdata->ctx; + struct cmd_ctx *ctx = cdata->ctx; struct cmd_list *cmdlist; char *cause, *cmd; @@ -105,14 +102,11 @@ void cmd_if_shell_free(void *data) { struct cmd_if_shell_data *cdata = data; - struct cmd_ctx *ctx = &cdata->ctx; + struct cmd_ctx *ctx = cdata->ctx; - if (ctx->cmdclient != NULL) { - ctx->cmdclient->references--; + if (ctx->cmdclient != NULL) ctx->cmdclient->flags |= CLIENT_EXIT; - } - if (ctx->curclient != NULL) - ctx->curclient->references--; + cmd_free_ctx(ctx); free(cdata->cmd_else); free(cdata->cmd_if); diff --git a/cmd-list.c b/cmd-list.c index 2cf66a80..d1e72e93 100644 --- a/cmd-list.c +++ b/cmd-list.c @@ -97,7 +97,7 @@ cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx) TAILQ_FOREACH(cmd, &cmdlist->list, qentry) { if (guards) ctx->print(ctx, "%%begin"); - n = cmd_exec(cmd, ctx); + n = cmd->entry->exec(cmd, ctx); if (guards) ctx->print(ctx, "%%end"); @@ -146,7 +146,8 @@ cmd_list_free(struct cmd_list *cmdlist) while (!TAILQ_EMPTY(&cmdlist->list)) { cmd = TAILQ_FIRST(&cmdlist->list); TAILQ_REMOVE(&cmdlist->list, cmd, qentry); - cmd_free(cmd); + args_free(cmd->args); + free(cmd); } free(cmdlist); } diff --git a/cmd-run-shell.c b/cmd-run-shell.c index 0fe7620b..ea7d1dcb 100644 --- a/cmd-run-shell.c +++ b/cmd-run-shell.c @@ -47,7 +47,7 @@ const struct cmd_entry cmd_run_shell_entry = { struct cmd_run_shell_data { char *cmd; - struct cmd_ctx ctx; + struct cmd_ctx *ctx; u_int wp_id; }; @@ -55,7 +55,7 @@ void cmd_run_shell_print(struct job *job, const char *msg) { struct cmd_run_shell_data *cdata = job->data; - struct cmd_ctx *ctx = &cdata->ctx; + struct cmd_ctx *ctx = cdata->ctx; struct window_pane *wp; wp = window_pane_find_by_id(cdata->wp_id); @@ -84,12 +84,9 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx) cdata = xmalloc(sizeof *cdata); cdata->cmd = xstrdup(args->argv[0]); cdata->wp_id = wp->id; - memcpy(&cdata->ctx, ctx, sizeof cdata->ctx); - if (ctx->cmdclient != NULL) - ctx->cmdclient->references++; - if (ctx->curclient != NULL) - ctx->curclient->references++; + cdata->ctx = ctx; + cmd_ref_ctx(ctx); job_run(shellcmd, cmd_run_shell_callback, cmd_run_shell_free, cdata); @@ -100,7 +97,7 @@ void cmd_run_shell_callback(struct job *job) { struct cmd_run_shell_data *cdata = job->data; - struct cmd_ctx *ctx = &cdata->ctx; + struct cmd_ctx *ctx = cdata->ctx; char *cmd, *msg, *line; size_t size; int retcode; @@ -154,14 +151,11 @@ void cmd_run_shell_free(void *data) { struct cmd_run_shell_data *cdata = data; - struct cmd_ctx *ctx = &cdata->ctx; + struct cmd_ctx *ctx = cdata->ctx; - if (ctx->cmdclient != NULL) { - ctx->cmdclient->references--; + if (ctx->cmdclient != NULL) ctx->cmdclient->flags |= CLIENT_EXIT; - } - if (ctx->curclient != NULL) - ctx->curclient->references--; + cmd_free_ctx(ctx); free(cdata->cmd); free(cdata); diff --git a/cmd.c b/cmd.c index 023a540d..beb3fb5e 100644 --- a/cmd.c +++ b/cmd.c @@ -133,6 +133,39 @@ struct winlink *cmd_find_window_offset(const char *, struct session *, int *); int cmd_find_index_offset(const char *, struct session *, int *); struct window_pane *cmd_find_pane_offset(const char *, struct winlink *); +struct cmd_ctx * +cmd_get_ctx(void) +{ + struct cmd_ctx *ctx; + + ctx = xcalloc(1, sizeof *ctx); + ctx->references = 0; + + cmd_ref_ctx(ctx); + return (ctx); +} + +void +cmd_free_ctx(struct cmd_ctx *ctx) +{ + if (ctx->cmdclient != NULL) + ctx->cmdclient->references--; + if (ctx->curclient != NULL) + ctx->curclient->references--; + if (--ctx->references == 0) + free(ctx); +} + +void +cmd_ref_ctx(struct cmd_ctx *ctx) +{ + ctx->references++; + if (ctx->cmdclient != NULL) + ctx->cmdclient->references++; + if (ctx->curclient != NULL) + ctx->curclient->references++; +} + int cmd_pack_argv(int argc, char **argv, char *buf, size_t len) { @@ -282,19 +315,6 @@ usage: return (NULL); } -enum cmd_retval -cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx) -{ - return (cmd->entry->exec(cmd, ctx)); -} - -void -cmd_free(struct cmd *cmd) -{ - args_free(cmd->args); - free(cmd); -} - size_t cmd_print(struct cmd *cmd, char *buf, size_t len) {