cmd-if-shell.c revision 1.2 1 1.2 christos /* $Id: cmd-if-shell.c,v 1.2 2013/10/20 03:00:02 christos 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.2 christos "", 2, 2,
39 1.1 jmmv "shell-command command",
40 1.2 christos 0,
41 1.2 christos NULL,
42 1.2 christos NULL,
43 1.2 christos cmd_if_shell_exec
44 1.1 jmmv };
45 1.1 jmmv
46 1.1 jmmv struct cmd_if_shell_data {
47 1.1 jmmv char *cmd;
48 1.1 jmmv struct cmd_ctx ctx;
49 1.1 jmmv };
50 1.1 jmmv
51 1.1 jmmv int
52 1.1 jmmv cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
53 1.1 jmmv {
54 1.2 christos struct args *args = self->args;
55 1.1 jmmv struct cmd_if_shell_data *cdata;
56 1.2 christos const char *shellcmd = args->argv[0];
57 1.1 jmmv
58 1.1 jmmv cdata = xmalloc(sizeof *cdata);
59 1.2 christos cdata->cmd = xstrdup(args->argv[1]);
60 1.1 jmmv memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
61 1.1 jmmv
62 1.1 jmmv if (ctx->cmdclient != NULL)
63 1.1 jmmv ctx->cmdclient->references++;
64 1.1 jmmv if (ctx->curclient != NULL)
65 1.1 jmmv ctx->curclient->references++;
66 1.1 jmmv
67 1.2 christos job_run(shellcmd, cmd_if_shell_callback, cmd_if_shell_free, cdata);
68 1.1 jmmv
69 1.1 jmmv return (1); /* don't let client exit */
70 1.1 jmmv }
71 1.1 jmmv
72 1.1 jmmv void
73 1.1 jmmv cmd_if_shell_callback(struct job *job)
74 1.1 jmmv {
75 1.1 jmmv struct cmd_if_shell_data *cdata = job->data;
76 1.1 jmmv struct cmd_ctx *ctx = &cdata->ctx;
77 1.1 jmmv struct cmd_list *cmdlist;
78 1.1 jmmv char *cause;
79 1.1 jmmv
80 1.1 jmmv if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0)
81 1.1 jmmv return;
82 1.1 jmmv
83 1.1 jmmv if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
84 1.1 jmmv if (cause != NULL) {
85 1.1 jmmv ctx->error(ctx, "%s", cause);
86 1.1 jmmv xfree(cause);
87 1.1 jmmv }
88 1.1 jmmv return;
89 1.1 jmmv }
90 1.1 jmmv
91 1.2 christos cmd_list_exec(cmdlist, ctx);
92 1.1 jmmv cmd_list_free(cmdlist);
93 1.1 jmmv }
94 1.1 jmmv
95 1.1 jmmv void
96 1.1 jmmv cmd_if_shell_free(void *data)
97 1.1 jmmv {
98 1.1 jmmv struct cmd_if_shell_data *cdata = data;
99 1.1 jmmv struct cmd_ctx *ctx = &cdata->ctx;
100 1.1 jmmv
101 1.1 jmmv if (ctx->cmdclient != NULL) {
102 1.1 jmmv ctx->cmdclient->references--;
103 1.1 jmmv ctx->cmdclient->flags |= CLIENT_EXIT;
104 1.1 jmmv }
105 1.1 jmmv if (ctx->curclient != NULL)
106 1.1 jmmv ctx->curclient->references--;
107 1.1 jmmv
108 1.1 jmmv xfree(cdata->cmd);
109 1.1 jmmv xfree(cdata);
110 1.1 jmmv }
111