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