Annotation of embedaddon/tmux/cmd-run-shell.c, revision 1.1
1.1 ! misho 1: /* $OpenBSD$ */
! 2:
! 3: /*
! 4: * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
! 5: * Copyright (c) 2009 Nicholas Marriott <nicm@openbsd.org>
! 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>
! 21: #include <sys/wait.h>
! 22:
! 23: #include <stdlib.h>
! 24: #include <string.h>
! 25:
! 26: #include "tmux.h"
! 27:
! 28: /*
! 29: * Runs a command without a window.
! 30: */
! 31:
! 32: static enum cmd_retval cmd_run_shell_exec(struct cmd *, struct cmdq_item *);
! 33:
! 34: static void cmd_run_shell_callback(struct job *);
! 35: static void cmd_run_shell_free(void *);
! 36: static void cmd_run_shell_print(struct job *, const char *);
! 37:
! 38: const struct cmd_entry cmd_run_shell_entry = {
! 39: .name = "run-shell",
! 40: .alias = "run",
! 41:
! 42: .args = { "bt:", 1, 1 },
! 43: .usage = "[-b] " CMD_TARGET_PANE_USAGE " shell-command",
! 44:
! 45: .tflag = CMD_PANE_CANFAIL,
! 46:
! 47: .flags = 0,
! 48: .exec = cmd_run_shell_exec
! 49: };
! 50:
! 51: struct cmd_run_shell_data {
! 52: char *cmd;
! 53: struct cmdq_item *item;
! 54: int wp_id;
! 55: };
! 56:
! 57: static void
! 58: cmd_run_shell_print(struct job *job, const char *msg)
! 59: {
! 60: struct cmd_run_shell_data *cdata = job->data;
! 61: struct window_pane *wp = NULL;
! 62: struct cmd_find_state fs;
! 63:
! 64: if (cdata->wp_id != -1)
! 65: wp = window_pane_find_by_id(cdata->wp_id);
! 66: if (wp == NULL) {
! 67: if (cdata->item != NULL) {
! 68: cmdq_print(cdata->item, "%s", msg);
! 69: return;
! 70: }
! 71: if (cmd_find_current (&fs, NULL, CMD_FIND_QUIET) != 0)
! 72: return;
! 73: wp = fs.wp;
! 74: if (wp == NULL)
! 75: return;
! 76: }
! 77:
! 78: if (window_pane_set_mode(wp, &window_copy_mode) == 0)
! 79: window_copy_init_for_output(wp);
! 80: if (wp->mode == &window_copy_mode)
! 81: window_copy_add(wp, "%s", msg);
! 82: }
! 83:
! 84: static enum cmd_retval
! 85: cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item)
! 86: {
! 87: struct args *args = self->args;
! 88: struct cmd_run_shell_data *cdata;
! 89: struct client *c = item->state.c;
! 90: struct session *s = item->state.tflag.s;
! 91: struct winlink *wl = item->state.tflag.wl;
! 92: struct window_pane *wp = item->state.tflag.wp;
! 93: const char *cwd;
! 94:
! 95: if (item->client != NULL && item->client->session == NULL)
! 96: cwd = item->client->cwd;
! 97: else if (s != NULL)
! 98: cwd = s->cwd;
! 99: else
! 100: cwd = NULL;
! 101:
! 102: cdata = xcalloc(1, sizeof *cdata);
! 103: cdata->cmd = format_single(item, args->argv[0], c, s, wl, wp);
! 104:
! 105: if (args_has(args, 't') && wp != NULL)
! 106: cdata->wp_id = wp->id;
! 107: else
! 108: cdata->wp_id = -1;
! 109:
! 110: if (!args_has(args, 'b'))
! 111: cdata->item = item;
! 112:
! 113: job_run(cdata->cmd, s, cwd, cmd_run_shell_callback, cmd_run_shell_free,
! 114: cdata);
! 115:
! 116: if (args_has(args, 'b'))
! 117: return (CMD_RETURN_NORMAL);
! 118: return (CMD_RETURN_WAIT);
! 119: }
! 120:
! 121: static void
! 122: cmd_run_shell_callback(struct job *job)
! 123: {
! 124: struct cmd_run_shell_data *cdata = job->data;
! 125: char *cmd = cdata->cmd, *msg, *line;
! 126: size_t size;
! 127: int retcode;
! 128:
! 129: do {
! 130: if ((line = evbuffer_readline(job->event->input)) != NULL) {
! 131: cmd_run_shell_print(job, line);
! 132: free(line);
! 133: }
! 134: } while (line != NULL);
! 135:
! 136: size = EVBUFFER_LENGTH(job->event->input);
! 137: if (size != 0) {
! 138: line = xmalloc(size + 1);
! 139: memcpy(line, EVBUFFER_DATA(job->event->input), size);
! 140: line[size] = '\0';
! 141:
! 142: cmd_run_shell_print(job, line);
! 143:
! 144: free(line);
! 145: }
! 146:
! 147: msg = NULL;
! 148: if (WIFEXITED(job->status)) {
! 149: if ((retcode = WEXITSTATUS(job->status)) != 0)
! 150: xasprintf(&msg, "'%s' returned %d", cmd, retcode);
! 151: } else if (WIFSIGNALED(job->status)) {
! 152: retcode = WTERMSIG(job->status);
! 153: xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode);
! 154: }
! 155: if (msg != NULL)
! 156: cmd_run_shell_print(job, msg);
! 157: free(msg);
! 158:
! 159: if (cdata->item != NULL)
! 160: cdata->item->flags &= ~CMDQ_WAITING;
! 161: }
! 162:
! 163: static void
! 164: cmd_run_shell_free(void *data)
! 165: {
! 166: struct cmd_run_shell_data *cdata = data;
! 167:
! 168: free(cdata->cmd);
! 169: free(cdata);
! 170: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>