mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Add a -C flag to run-shell to use a tmux command rather than a shell command.
This commit is contained in:
		| @@ -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); | ||||
| 		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); | ||||
|   | ||||
							
								
								
									
										23
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								tmux.1
									
									
									
									
									
								
							| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 nicm
					nicm