Annotation of src/usr.bin/tmux/cmd-if-shell.c, Revision 1.11
1.11 ! nicm 1: /* $OpenBSD: cmd-if-shell.c,v 1.10 2011/01/04 00:42:46 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:
23: #include <string.h>
24:
25: #include "tmux.h"
26:
27: /*
28: * Executes a tmux command if a shell command returns true.
29: */
30:
31: int cmd_if_shell_exec(struct cmd *, struct cmd_ctx *);
32:
1.5 nicm 33: void cmd_if_shell_callback(struct job *);
34: void cmd_if_shell_free(void *);
1.1 nicm 35:
36: const struct cmd_entry cmd_if_shell_entry = {
37: "if-shell", "if",
1.10 nicm 38: "", 2, 2,
1.1 nicm 39: "shell-command command",
1.10 nicm 40: 0,
41: NULL,
42: NULL,
43: cmd_if_shell_exec
1.1 nicm 44: };
45:
1.5 nicm 46: struct cmd_if_shell_data {
47: char *cmd;
48: struct cmd_ctx ctx;
49: };
1.1 nicm 50:
51: int
1.5 nicm 52: cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
1.1 nicm 53: {
1.10 nicm 54: struct args *args = self->args;
1.5 nicm 55: struct cmd_if_shell_data *cdata;
1.11 ! nicm 56: const char *shellcmd = args->argv[0];
1.5 nicm 57:
58: cdata = xmalloc(sizeof *cdata);
1.10 nicm 59: cdata->cmd = xstrdup(args->argv[1]);
1.5 nicm 60: memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
61:
62: if (ctx->cmdclient != NULL)
63: ctx->cmdclient->references++;
64: if (ctx->curclient != NULL)
65: ctx->curclient->references++;
66:
1.11 ! nicm 67: job_run(shellcmd, cmd_if_shell_callback, cmd_if_shell_free, cdata);
1.1 nicm 68:
1.5 nicm 69: return (1); /* don't let client exit */
1.1 nicm 70: }
71:
1.5 nicm 72: void
73: cmd_if_shell_callback(struct job *job)
1.1 nicm 74: {
1.5 nicm 75: struct cmd_if_shell_data *cdata = job->data;
76: struct cmd_ctx *ctx = &cdata->ctx;
1.1 nicm 77: struct cmd_list *cmdlist;
78: char *cause;
79:
1.6 nicm 80: if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0)
1.5 nicm 81: return;
1.1 nicm 82:
1.5 nicm 83: if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
1.1 nicm 84: if (cause != NULL) {
85: ctx->error(ctx, "%s", cause);
86: xfree(cause);
87: }
1.5 nicm 88: return;
1.1 nicm 89: }
90:
91: if (cmd_list_exec(cmdlist, ctx) < 0) {
92: cmd_list_free(cmdlist);
1.5 nicm 93: return;
1.1 nicm 94: }
95:
96: cmd_list_free(cmdlist);
97: }
98:
99: void
1.5 nicm 100: cmd_if_shell_free(void *data)
1.1 nicm 101: {
1.5 nicm 102: struct cmd_if_shell_data *cdata = data;
103: struct cmd_ctx *ctx = &cdata->ctx;
1.8 nicm 104: struct msg_exit_data exitdata;
1.1 nicm 105:
1.5 nicm 106: if (ctx->cmdclient != NULL) {
107: ctx->cmdclient->references--;
1.8 nicm 108: exitdata.retcode = ctx->cmdclient->retcode;
1.9 nicm 109: ctx->cmdclient->flags |= CLIENT_EXIT;
1.5 nicm 110: }
111: if (ctx->curclient != NULL)
112: ctx->curclient->references--;
1.1 nicm 113:
1.5 nicm 114: xfree(cdata->cmd);
115: xfree(cdata);
1.1 nicm 116: }