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", | 	.name = "run-shell", | ||||||
| 	.alias = "run", | 	.alias = "run", | ||||||
|  |  | ||||||
| 	.args = { "bd:t:", 0, 1 }, | 	.args = { "bd:Ct:", 0, 1 }, | ||||||
| 	.usage = "[-b] [-d delay] " CMD_TARGET_PANE_USAGE " [shell-command]", | 	.usage = "[-bC] [-d delay] " CMD_TARGET_PANE_USAGE " [shell-command]", | ||||||
|  |  | ||||||
| 	.target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL }, | 	.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 cmd_run_shell_data { | ||||||
|  | 	struct client		*client; | ||||||
| 	char			*cmd; | 	char			*cmd; | ||||||
|  | 	int			 shell; | ||||||
| 	char			*cwd; | 	char			*cwd; | ||||||
| 	struct cmdq_item	*item; | 	struct cmdq_item	*item; | ||||||
| 	struct session		*s; | 	struct session		*s; | ||||||
| 	int			 wp_id; | 	int			 wp_id; | ||||||
| 	struct event		 timer; | 	struct event		 timer; | ||||||
| 	int			 flags; | 	int			 flags; | ||||||
|  | 	struct cmd_parse_input	 pi; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static void | 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 args			*args = cmd_get_args(self); | ||||||
| 	struct cmd_find_state		*target = cmdq_get_target(item); | 	struct cmd_find_state		*target = cmdq_get_target(item); | ||||||
| 	struct cmd_run_shell_data	*cdata; | 	struct cmd_run_shell_data	*cdata; | ||||||
|  | 	struct client			*tc = cmdq_get_target_client(item); | ||||||
| 	struct session			*s = target->s; | 	struct session			*s = target->s; | ||||||
| 	struct window_pane		*wp = target->wp; | 	struct window_pane		*wp = target->wp; | ||||||
| 	const char			*delay; | 	const char			*delay; | ||||||
| 	double				 d; | 	double				 d; | ||||||
| 	struct timeval			 tv; | 	struct timeval			 tv; | ||||||
| 	char				*end; | 	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); | 	cdata = xcalloc(1, sizeof *cdata); | ||||||
| 	if (args->argc != 0) | 	if (args->argc != 0) | ||||||
| 		cdata->cmd = format_single_from_target(item, args->argv[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) | 	if (args_has(args, 't') && wp != NULL) | ||||||
| 		cdata->wp_id = wp->id; | 		cdata->wp_id = wp->id; | ||||||
| 	else | 	else | ||||||
| 		cdata->wp_id = -1; | 		cdata->wp_id = -1; | ||||||
|  |  | ||||||
| 	if (!args_has(args, 'b')) | 	if (wait) { | ||||||
|  | 		cdata->client = cmdq_get_client(item); | ||||||
| 		cdata->item = item; | 		cdata->item = item; | ||||||
| 	else | 	} else { | ||||||
|  | 		cdata->client = tc; | ||||||
| 		cdata->flags |= JOB_NOWAIT; | 		cdata->flags |= JOB_NOWAIT; | ||||||
|  | 	} | ||||||
|  | 	if (cdata->client != NULL) | ||||||
|  | 		cdata->client->references++; | ||||||
|  |  | ||||||
| 	cdata->cwd = xstrdup(server_client_get_cwd(cmdq_get_client(item), s)); | 	cdata->cwd = xstrdup(server_client_get_cwd(cmdq_get_client(item), s)); | ||||||
|  |  | ||||||
| 	cdata->s = s; | 	cdata->s = s; | ||||||
| 	if (s != NULL) | 	if (s != NULL) | ||||||
| 		session_add_ref(s, __func__); | 		session_add_ref(s, __func__); | ||||||
|  |  | ||||||
| 	evtimer_set(&cdata->timer, cmd_run_shell_timer, cdata); | 	evtimer_set(&cdata->timer, cmd_run_shell_timer, cdata); | ||||||
|  | 	if (delay != NULL) { | ||||||
| 	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); |  | ||||||
| 		} |  | ||||||
| 		timerclear(&tv); | 		timerclear(&tv); | ||||||
| 		tv.tv_sec = (time_t)d; | 		tv.tv_sec = (time_t)d; | ||||||
| 		tv.tv_usec = (d - (double)tv.tv_sec) * 1000000U; | 		tv.tv_usec = (d - (double)tv.tv_sec) * 1000000U; | ||||||
| 		evtimer_add(&cdata->timer, &tv); | 		evtimer_add(&cdata->timer, &tv); | ||||||
| 	} else | 	} 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_NORMAL); | ||||||
| 	return (CMD_RETURN_WAIT); | 	return (CMD_RETURN_WAIT); | ||||||
| } | } | ||||||
| @@ -144,17 +167,37 @@ static void | |||||||
| cmd_run_shell_timer(__unused int fd, __unused short events, void* arg) | cmd_run_shell_timer(__unused int fd, __unused short events, void* arg) | ||||||
| { | { | ||||||
| 	struct cmd_run_shell_data	*cdata = 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 (cmd != NULL && cdata->shell) { | ||||||
| 		if (job_run(cdata->cmd, cdata->s, cdata->cwd, NULL, | 		if (job_run(cmd, cdata->s, cdata->cwd, NULL, | ||||||
| 		    cmd_run_shell_callback, cmd_run_shell_free, cdata, | 		    cmd_run_shell_callback, cmd_run_shell_free, cdata, | ||||||
| 		    cdata->flags, -1, -1) == NULL) | 		    cdata->flags, -1, -1) == NULL) | ||||||
| 			cmd_run_shell_free(cdata); | 			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 { | 		} 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) | 	if (cdata->item != NULL) | ||||||
| 		cmdq_continue(cdata->item); | 		cmdq_continue(cdata->item); | ||||||
| 	cmd_run_shell_free(cdata); | 	cmd_run_shell_free(cdata); | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| @@ -215,6 +258,8 @@ cmd_run_shell_free(void *data) | |||||||
| 	evtimer_del(&cdata->timer); | 	evtimer_del(&cdata->timer); | ||||||
| 	if (cdata->s != NULL) | 	if (cdata->s != NULL) | ||||||
| 		session_remove_ref(cdata->s, __func__); | 		session_remove_ref(cdata->s, __func__); | ||||||
|  | 	if (cdata->client != NULL) | ||||||
|  | 		server_client_unref(cdata->client); | ||||||
| 	free(cdata->cwd); | 	free(cdata->cwd); | ||||||
| 	free(cdata->cmd); | 	free(cdata->cmd); | ||||||
| 	free(cdata); | 	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 | .Ic lock-command | ||||||
| option. | option. | ||||||
| .It Xo Ic run-shell | .It Xo Ic run-shell | ||||||
| .Op Fl b | .Op Fl bC | ||||||
| .Op Fl d Ar delay | .Op Fl d Ar delay | ||||||
| .Op Fl t Ar target-pane | .Op Fl t Ar target-pane | ||||||
| .Op Ar shell-command | .Op Ar shell-command | ||||||
| @@ -5835,9 +5835,14 @@ option. | |||||||
| .D1 (alias: Ic run ) | .D1 (alias: Ic run ) | ||||||
| Execute | Execute | ||||||
| .Ar shell-command | .Ar shell-command | ||||||
| in the background without creating a window. | or (with | ||||||
| Before being executed, shell-command is expanded using the rules specified in | .Fl C ) | ||||||
| the | 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 | .Sx FORMATS | ||||||
| section. | section. | ||||||
| With | With | ||||||
| @@ -5847,11 +5852,13 @@ the command is run in the background. | |||||||
| waits for | waits for | ||||||
| .Ar delay | .Ar delay | ||||||
| seconds before starting the command. | seconds before starting the command. | ||||||
| After the command finishes, any output to stdout is displayed in view mode (in | If | ||||||
| the pane specified by | .Fl C | ||||||
|  | is not given, any output to stdout is displayed in view mode (in the pane | ||||||
|  | specified by | ||||||
| .Fl t | .Fl t | ||||||
| or the current pane if omitted). | or the current pane if omitted) after the command finishes. | ||||||
| If the command doesn't return success, the exit status is also displayed. | If the command fails, the exit status is also displayed. | ||||||
| .It Xo Ic wait-for | .It Xo Ic wait-for | ||||||
| .Op Fl L | S | U | .Op Fl L | S | U | ||||||
| .Ar channel | .Ar channel | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 nicm
					nicm