=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/cmd-if-shell.c,v retrieving revision 1.19 retrieving revision 1.20 diff -c -r1.19 -r1.20 *** src/usr.bin/tmux/cmd-if-shell.c 2013/03/24 09:33:35 1.19 --- src/usr.bin/tmux/cmd-if-shell.c 2013/03/24 09:54:10 1.20 *************** *** 1,4 **** ! /* $OpenBSD: cmd-if-shell.c,v 1.19 2013/03/24 09:33:35 nicm Exp $ */ /* * Copyright (c) 2009 Tiago Cunha --- 1,4 ---- ! /* $OpenBSD: cmd-if-shell.c,v 1.20 2013/03/24 09:54:10 nicm Exp $ */ /* * Copyright (c) 2009 Tiago Cunha *************** *** 29,43 **** * Executes a tmux command if a shell command returns true or false. */ ! enum cmd_retval cmd_if_shell_exec(struct cmd *, struct cmd_ctx *); void cmd_if_shell_callback(struct job *); void cmd_if_shell_free(void *); const struct cmd_entry cmd_if_shell_entry = { "if-shell", "if", ! "t:", 2, 3, ! CMD_TARGET_PANE_USAGE " shell-command command [command]", 0, NULL, NULL, --- 29,44 ---- * Executes a tmux command if a shell command returns true or false. */ ! enum cmd_retval cmd_if_shell_exec(struct cmd *, struct cmd_q *); void cmd_if_shell_callback(struct job *); + void cmd_if_shell_done(struct cmd_q *); void cmd_if_shell_free(void *); const struct cmd_entry cmd_if_shell_entry = { "if-shell", "if", ! "bt:", 2, 3, ! "[-b] " CMD_TARGET_PANE_USAGE " shell-command command [command]", 0, NULL, NULL, *************** *** 47,57 **** struct cmd_if_shell_data { char *cmd_if; char *cmd_else; ! struct cmd_ctx *ctx; }; enum cmd_retval ! cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct cmd_if_shell_data *cdata; --- 48,60 ---- struct cmd_if_shell_data { char *cmd_if; char *cmd_else; ! struct cmd_q *cmdq; ! int bflag; ! int started; }; enum cmd_retval ! cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct cmd_if_shell_data *cdata; *************** *** 61,67 **** struct window_pane *wp; struct format_tree *ft; ! wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp); if (wl == NULL) return (CMD_RETURN_ERROR); --- 64,70 ---- struct window_pane *wp; struct format_tree *ft; ! wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp); if (wl == NULL) return (CMD_RETURN_ERROR); *************** *** 78,128 **** cdata->cmd_else = xstrdup(args->argv[2]); else cdata->cmd_else = NULL; ! cdata->ctx = ctx; ! cmd_ref_ctx(ctx); job_run(shellcmd, cmd_if_shell_callback, cmd_if_shell_free, cdata); free(shellcmd); ! return (CMD_RETURN_YIELD); /* don't let client exit */ } void cmd_if_shell_callback(struct job *job) { struct cmd_if_shell_data *cdata = job->data; ! struct cmd_ctx *ctx = cdata->ctx; struct cmd_list *cmdlist; char *cause, *cmd; ! if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0) { cmd = cdata->cmd_else; ! if (cmd == NULL) ! return; ! } else cmd = cdata->cmd_if; ! if (cmd_string_parse(cmd, &cmdlist, &cause) != 0) { if (cause != NULL) { ! ctx->error(ctx, "%s", cause); free(cause); } return; } ! cmd_list_exec(cmdlist, ctx); cmd_list_free(cmdlist); } void cmd_if_shell_free(void *data) { struct cmd_if_shell_data *cdata = data; ! struct cmd_ctx *ctx = cdata->ctx; ! if (ctx->cmdclient != NULL) ! ctx->cmdclient->flags |= CLIENT_EXIT; ! cmd_free_ctx(ctx); free(cdata->cmd_else); free(cdata->cmd_if); --- 81,163 ---- cdata->cmd_else = xstrdup(args->argv[2]); else cdata->cmd_else = NULL; + cdata->bflag = args_has(args, 'b'); ! cdata->started = 0; ! cdata->cmdq = cmdq; ! cmdq->references++; job_run(shellcmd, cmd_if_shell_callback, cmd_if_shell_free, cdata); free(shellcmd); ! if (cdata->bflag) ! return (CMD_RETURN_NORMAL); ! return (CMD_RETURN_WAIT); } void cmd_if_shell_callback(struct job *job) { struct cmd_if_shell_data *cdata = job->data; ! struct cmd_q *cmdq = cdata->cmdq, *cmdq1; struct cmd_list *cmdlist; char *cause, *cmd; ! if (cmdq->dead) ! return; ! ! if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0) cmd = cdata->cmd_else; ! else cmd = cdata->cmd_if; ! if (cmd == NULL) ! return; ! ! if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) { if (cause != NULL) { ! cmdq_error(cmdq, "%s", cause); free(cause); } return; } ! cdata->started = 1; ! ! cmdq1 = cmdq_new(cmdq->client); ! cmdq1->emptyfn = cmd_if_shell_done; ! cmdq1->data = cdata; ! ! cmdq_run(cmdq1, cmdlist); cmd_list_free(cmdlist); } void + cmd_if_shell_done(struct cmd_q *cmdq1) + { + struct cmd_if_shell_data *cdata = cmdq1->data; + struct cmd_q *cmdq = cdata->cmdq; + + if (!cmdq_free(cmdq) && !cdata->bflag) + cmdq_continue(cmdq); + + cmdq_free(cmdq1); + + free(cdata->cmd_else); + free(cdata->cmd_if); + free(cdata); + } + + void cmd_if_shell_free(void *data) { struct cmd_if_shell_data *cdata = data; ! struct cmd_q *cmdq = cdata->cmdq; ! if (cdata->started) ! return; ! ! if (!cmdq_free(cmdq) && !cdata->bflag) ! cmdq_continue(cmdq); free(cdata->cmd_else); free(cdata->cmd_if);