Annotation of src/usr.bin/tmux/cmd-if-shell.c, Revision 1.17
1.17 ! nicm 1: /* $OpenBSD: cmd-if-shell.c,v 1.16 2012/07/11 07:10:15 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
1.5 nicm 5: * Copyright (c) 2009 Nicholas Marriott <nicm@openbsd.org>
1.1 nicm 6: *
7: * Permission to use, copy, modify, and distribute this software for any
8: * purpose with or without fee is hereby granted, provided that the above
9: * copyright notice and this permission notice appear in all copies.
10: *
11: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
16: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
17: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18: */
19:
20: #include <sys/types.h>
1.5 nicm 21: #include <sys/wait.h>
1.1 nicm 22:
1.15 nicm 23: #include <stdlib.h>
1.1 nicm 24: #include <string.h>
25:
26: #include "tmux.h"
27:
28: /*
1.14 nicm 29: * Executes a tmux command if a shell command returns true or false.
1.1 nicm 30: */
31:
1.16 nicm 32: enum cmd_retval cmd_if_shell_exec(struct cmd *, struct cmd_ctx *);
1.1 nicm 33:
1.5 nicm 34: void cmd_if_shell_callback(struct job *);
35: void cmd_if_shell_free(void *);
1.1 nicm 36:
37: const struct cmd_entry cmd_if_shell_entry = {
38: "if-shell", "if",
1.14 nicm 39: "", 2, 3,
40: "shell-command command [command]",
1.10 nicm 41: 0,
42: NULL,
1.14 nicm 43: NULL,
1.10 nicm 44: cmd_if_shell_exec
1.1 nicm 45: };
46:
1.5 nicm 47: struct cmd_if_shell_data {
1.13 nicm 48: char *cmd_if;
49: char *cmd_else;
1.5 nicm 50: struct cmd_ctx ctx;
51: };
1.1 nicm 52:
1.16 nicm 53: enum cmd_retval
1.5 nicm 54: cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
1.1 nicm 55: {
1.10 nicm 56: struct args *args = self->args;
1.5 nicm 57: struct cmd_if_shell_data *cdata;
1.11 nicm 58: const char *shellcmd = args->argv[0];
1.5 nicm 59:
60: cdata = xmalloc(sizeof *cdata);
1.13 nicm 61: cdata->cmd_if = xstrdup(args->argv[1]);
1.14 nicm 62: if (args->argc == 3)
63: cdata->cmd_else = xstrdup(args->argv[2]);
1.13 nicm 64: else
65: cdata->cmd_else = NULL;
1.5 nicm 66: memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
67:
68: if (ctx->cmdclient != NULL)
69: ctx->cmdclient->references++;
70: if (ctx->curclient != NULL)
71: ctx->curclient->references++;
72:
1.11 nicm 73: job_run(shellcmd, cmd_if_shell_callback, cmd_if_shell_free, cdata);
1.1 nicm 74:
1.16 nicm 75: return (CMD_RETURN_YIELD); /* don't let client exit */
1.1 nicm 76: }
77:
1.5 nicm 78: void
79: cmd_if_shell_callback(struct job *job)
1.1 nicm 80: {
1.5 nicm 81: struct cmd_if_shell_data *cdata = job->data;
82: struct cmd_ctx *ctx = &cdata->ctx;
1.1 nicm 83: struct cmd_list *cmdlist;
1.14 nicm 84: char *cause, *cmd;
1.1 nicm 85:
1.13 nicm 86: if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0) {
87: cmd = cdata->cmd_else;
88: if (cmd == NULL)
89: return;
90: } else
91: cmd = cdata->cmd_if;
92: if (cmd_string_parse(cmd, &cmdlist, &cause) != 0) {
1.1 nicm 93: if (cause != NULL) {
94: ctx->error(ctx, "%s", cause);
1.15 nicm 95: free(cause);
1.1 nicm 96: }
1.5 nicm 97: return;
1.1 nicm 98: }
99:
1.12 nicm 100: cmd_list_exec(cmdlist, ctx);
1.1 nicm 101: cmd_list_free(cmdlist);
102: }
103:
104: void
1.5 nicm 105: cmd_if_shell_free(void *data)
1.1 nicm 106: {
1.5 nicm 107: struct cmd_if_shell_data *cdata = data;
108: struct cmd_ctx *ctx = &cdata->ctx;
1.1 nicm 109:
1.5 nicm 110: if (ctx->cmdclient != NULL) {
111: ctx->cmdclient->references--;
1.9 nicm 112: ctx->cmdclient->flags |= CLIENT_EXIT;
1.5 nicm 113: }
114: if (ctx->curclient != NULL)
115: ctx->curclient->references--;
1.1 nicm 116:
1.15 nicm 117: free(cdata->cmd_else);
118: free(cdata->cmd_if);
119: free(cdata);
1.1 nicm 120: }