diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2021-01-01 08:36:52 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2021-01-01 08:36:52 +0000 |
commit | fa75537befca06a0d1f1a609874051564636cce6 (patch) | |
tree | 247fa199d478ff8fa5978372975c67b5d01ca308 /usr.bin/tmux | |
parent | ce97ff30b65ca4aebd54404963024cce7b4feb9b (diff) |
Add a -C flag to run-shell to use a tmux command rather than a shell command.
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r-- | usr.bin/tmux/cmd-run-shell.c | 87 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 27 |
2 files changed, 83 insertions, 31 deletions
diff --git a/usr.bin/tmux/cmd-run-shell.c b/usr.bin/tmux/cmd-run-shell.c index d8b4e539a82..053cd6bf49b 100644 --- a/usr.bin/tmux/cmd-run-shell.c +++ b/usr.bin/tmux/cmd-run-shell.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-run-shell.c,v 1.69 2020/06/12 10:31:12 nicm Exp $ */ +/* $OpenBSD: cmd-run-shell.c,v 1.70 2021/01/01 08:36:51 nicm Exp $ */ /* * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org> @@ -40,8 +40,8 @@ const struct cmd_entry cmd_run_shell_entry = { .name = "run-shell", .alias = "run", - .args = { "bd:t:", 0, 1 }, - .usage = "[-b] [-d delay] " CMD_TARGET_PANE_USAGE " [shell-command]", + .args = { "bd:Ct:", 0, 1 }, + .usage = "[-bC] [-d delay] " CMD_TARGET_PANE_USAGE " [shell-command]", .target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL }, @@ -50,13 +50,16 @@ const struct cmd_entry cmd_run_shell_entry = { }; struct cmd_run_shell_data { + struct client *client; char *cmd; + int shell; char *cwd; struct cmdq_item *item; struct session *s; int wp_id; struct event timer; int flags; + struct cmd_parse_input pi; }; static void @@ -93,49 +96,69 @@ cmd_run_shell_exec(struct cmd *self, struct cmdq_item *item) struct args *args = cmd_get_args(self); struct cmd_find_state *target = cmdq_get_target(item); struct cmd_run_shell_data *cdata; + struct client *tc = cmdq_get_target_client(item); struct session *s = target->s; struct window_pane *wp = target->wp; const char *delay; double d; struct timeval tv; char *end; + int wait = !args_has(args, 'b'); + + if ((delay = args_get(args, 'd')) != NULL) { + d = strtod(delay, &end); + if (*end != '\0') { + cmdq_error(item, "invalid delay time: %s", delay); + return (CMD_RETURN_ERROR); + } + } else if (args->argc == 0) + return (CMD_RETURN_NORMAL); cdata = xcalloc(1, sizeof *cdata); if (args->argc != 0) cdata->cmd = format_single_from_target(item, args->argv[0]); + cdata->shell = !args_has(args, 'C'); + if (!cdata->shell) { + memset(&cdata->pi, 0, sizeof cdata->pi); + cmd_get_source(self, &cdata->pi.file, &cdata->pi.line); + if (wait) + cdata->pi.item = item; + cdata->pi.c = tc; + cmd_find_copy_state(&cdata->pi.fs, target); + } + if (args_has(args, 't') && wp != NULL) cdata->wp_id = wp->id; else cdata->wp_id = -1; - if (!args_has(args, 'b')) + if (wait) { + cdata->client = cmdq_get_client(item); cdata->item = item; - else + } else { + cdata->client = tc; cdata->flags |= JOB_NOWAIT; + } + if (cdata->client != NULL) + cdata->client->references++; cdata->cwd = xstrdup(server_client_get_cwd(cmdq_get_client(item), s)); + cdata->s = s; if (s != NULL) session_add_ref(s, __func__); evtimer_set(&cdata->timer, cmd_run_shell_timer, cdata); - - if ((delay = args_get(args, 'd')) != NULL) { - d = strtod(delay, &end); - if (*end != '\0') { - cmdq_error(item, "invalid delay time: %s", delay); - cmd_run_shell_free(cdata); - return (CMD_RETURN_ERROR); - } + if (delay != NULL) { timerclear(&tv); tv.tv_sec = (time_t)d; tv.tv_usec = (d - (double)tv.tv_sec) * 1000000U; evtimer_add(&cdata->timer, &tv); } else - cmd_run_shell_timer(-1, 0, cdata); + event_active(&cdata->timer, EV_TIMEOUT, 1); - if (args_has(args, 'b')) + if (!wait) return (CMD_RETURN_NORMAL); return (CMD_RETURN_WAIT); } @@ -144,17 +167,37 @@ static void cmd_run_shell_timer(__unused int fd, __unused short events, void* arg) { struct cmd_run_shell_data *cdata = arg; + struct client *c = cdata->client; + const char *cmd = cdata->cmd; + char *error; + struct cmdq_item *item = cdata->item; + enum cmd_parse_status status; - if (cdata->cmd != NULL) { - if (job_run(cdata->cmd, cdata->s, cdata->cwd, NULL, + if (cmd != NULL && cdata->shell) { + if (job_run(cmd, cdata->s, cdata->cwd, NULL, cmd_run_shell_callback, cmd_run_shell_free, cdata, cdata->flags, -1, -1) == NULL) cmd_run_shell_free(cdata); - } else { - if (cdata->item != NULL) - cmdq_continue(cdata->item); - cmd_run_shell_free(cdata); + return; } + + if (cmd != NULL) { + if (item != NULL) { + status = cmd_parse_and_insert(cmd, &cdata->pi, item, + cmdq_get_state(item), &error); + } else { + status = cmd_parse_and_append(cmd, &cdata->pi, c, NULL, + &error); + } + if (status == CMD_PARSE_ERROR) { + cmdq_error(cdata->item, "%s", error); + free(error); + } + } + + if (cdata->item != NULL) + cmdq_continue(cdata->item); + cmd_run_shell_free(cdata); } static void @@ -215,6 +258,8 @@ cmd_run_shell_free(void *data) evtimer_del(&cdata->timer); if (cdata->s != NULL) session_remove_ref(cdata->s, __func__); + if (cdata->client != NULL) + server_client_unref(cdata->client); free(cdata->cwd); free(cdata->cmd); free(cdata); diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index e1e735d4c91..2678c04d1eb 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.808 2020/12/15 08:31:50 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.809 2021/01/01 08:36:51 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 15 2020 $ +.Dd $Mdocdate: January 1 2021 $ .Dt TMUX 1 .Os .Sh NAME @@ -5827,7 +5827,7 @@ Lock each client individually by running the command specified by the .Ic lock-command option. .It Xo Ic run-shell -.Op Fl b +.Op Fl bC .Op Fl d Ar delay .Op Fl t Ar target-pane .Op Ar shell-command @@ -5835,9 +5835,14 @@ option. .D1 (alias: Ic run ) Execute .Ar shell-command -in the background without creating a window. -Before being executed, shell-command is expanded using the rules specified in -the +or (with +.Fl C ) +a +.Nm +command in the background without creating a window. +Before being executed, +.Ar shell-command +is expanded using the rules specified in the .Sx FORMATS section. With @@ -5847,11 +5852,13 @@ the command is run in the background. waits for .Ar delay seconds before starting the command. -After the command finishes, any output to stdout is displayed in view mode (in -the pane specified by +If +.Fl C +is not given, any output to stdout is displayed in view mode (in the pane +specified by .Fl t -or the current pane if omitted). -If the command doesn't return success, the exit status is also displayed. +or the current pane if omitted) after the command finishes. +If the command fails, the exit status is also displayed. .It Xo Ic wait-for .Op Fl L | S | U .Ar channel |