Annotation of src/usr.bin/tmux/cmd-if-shell.c, Revision 1.5
1.5 ! nicm 1: /* $OpenBSD: cmd-if-shell.c,v 1.4 2009/09/21 15:32:06 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",
38: "shell-command command",
1.5 ! nicm 39: CMD_ARG2, 0,
! 40: cmd_target_init,
! 41: cmd_target_parse,
1.1 nicm 42: cmd_if_shell_exec,
1.5 ! nicm 43: cmd_target_free,
! 44: cmd_target_print
1.1 nicm 45: };
46:
1.5 ! nicm 47: struct cmd_if_shell_data {
! 48: char *cmd;
! 49: struct cmd_ctx ctx;
! 50: };
1.1 nicm 51:
52: int
1.5 ! nicm 53: cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
1.1 nicm 54: {
1.5 ! nicm 55: struct cmd_target_data *data = self->data;
! 56: struct cmd_if_shell_data *cdata;
! 57: struct job *job;
! 58:
! 59: cdata = xmalloc(sizeof *cdata);
! 60: cdata->cmd = xstrdup(data->arg2);
! 61: memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
! 62:
! 63: if (ctx->cmdclient != NULL)
! 64: ctx->cmdclient->references++;
! 65: if (ctx->curclient != NULL)
! 66: ctx->curclient->references++;
! 67:
! 68: job = job_add(NULL, NULL,
! 69: data->arg, cmd_if_shell_callback, cmd_if_shell_free, cdata);
! 70: job_run(job);
1.1 nicm 71:
1.5 ! nicm 72: return (1); /* don't let client exit */
1.1 nicm 73: }
74:
1.5 ! nicm 75: void
! 76: cmd_if_shell_callback(struct job *job)
1.1 nicm 77: {
1.5 ! nicm 78: struct cmd_if_shell_data *cdata = job->data;
! 79: struct cmd_ctx *ctx = &cdata->ctx;
1.1 nicm 80: struct cmd_list *cmdlist;
81: char *cause;
82:
1.5 ! nicm 83: if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0) {
! 84: job_free(job); /* calls cmd_if_shell_free */
! 85: return;
! 86: }
1.1 nicm 87:
1.5 ! nicm 88: if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
1.1 nicm 89: if (cause != NULL) {
90: ctx->error(ctx, "%s", cause);
91: xfree(cause);
92: }
1.5 ! nicm 93: return;
1.1 nicm 94: }
95:
96: if (cmd_list_exec(cmdlist, ctx) < 0) {
97: cmd_list_free(cmdlist);
1.5 ! nicm 98: return;
1.1 nicm 99: }
100:
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--;
! 112: server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
! 113: }
! 114: if (ctx->curclient != NULL)
! 115: ctx->curclient->references--;
1.1 nicm 116:
1.5 ! nicm 117: xfree(cdata->cmd);
! 118: xfree(cdata);
1.1 nicm 119: }