mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Add a timeout to prevent the sequences which wait for a specific
terminator (OSC, APC and DCS) waiting forever, which helps to avoid garbage (cat /dev/random) locking up panes completely. This (and the last commit) prompted by a discussion with theo.
This commit is contained in:
		
							
								
								
									
										58
									
								
								input.c
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								input.c
									
									
									
									
									
								
							| @@ -93,6 +93,8 @@ struct input_ctx { | |||||||
|  |  | ||||||
| 	const struct input_state *state; | 	const struct input_state *state; | ||||||
|  |  | ||||||
|  | 	struct event		timer; | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 * All input received since we were last in the ground state. Sent to | 	 * All input received since we were last in the ground state. Sent to | ||||||
| 	 * control clients on connection. | 	 * control clients on connection. | ||||||
| @@ -118,6 +120,7 @@ static void	input_osc_104(struct window_pane *, const char *); | |||||||
| /* Transition entry/exit handlers. */ | /* Transition entry/exit handlers. */ | ||||||
| static void	input_clear(struct input_ctx *); | static void	input_clear(struct input_ctx *); | ||||||
| static void	input_ground(struct input_ctx *); | static void	input_ground(struct input_ctx *); | ||||||
|  | static void	input_enter_dcs(struct input_ctx *); | ||||||
| static void	input_enter_osc(struct input_ctx *); | static void	input_enter_osc(struct input_ctx *); | ||||||
| static void	input_exit_osc(struct input_ctx *); | static void	input_exit_osc(struct input_ctx *); | ||||||
| static void	input_enter_apc(struct input_ctx *); | static void	input_enter_apc(struct input_ctx *); | ||||||
| @@ -364,7 +367,7 @@ static const struct input_state input_state_csi_ignore = { | |||||||
| /* dcs_enter state definition. */ | /* dcs_enter state definition. */ | ||||||
| static const struct input_state input_state_dcs_enter = { | static const struct input_state input_state_dcs_enter = { | ||||||
| 	"dcs_enter", | 	"dcs_enter", | ||||||
| 	input_clear, NULL, | 	input_enter_dcs, NULL, | ||||||
| 	input_state_dcs_enter_table | 	input_state_dcs_enter_table | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -756,6 +759,30 @@ input_table_compare(const void *key, const void *value) | |||||||
| 	return (strcmp(ictx->interm_buf, entry->interm)); | 	return (strcmp(ictx->interm_buf, entry->interm)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Timer - if this expires then have been waiting for a terminator for too | ||||||
|  |  * long, so reset to ground. | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | input_timer_callback(__unused int fd, __unused short events, void *arg) | ||||||
|  | { | ||||||
|  | 	struct input_ctx	*ictx = arg; | ||||||
|  | 	struct window_pane	*wp = ictx->wp; | ||||||
|  |  | ||||||
|  | 	log_debug("%s: %%%u %s expired" , __func__, wp->id, ictx->state->name); | ||||||
|  | 	input_reset(wp, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Start the timer. */ | ||||||
|  | static void | ||||||
|  | input_start_timer(struct input_ctx *ictx) | ||||||
|  | { | ||||||
|  | 	struct timeval	tv = { .tv_usec = 100000 }; | ||||||
|  |  | ||||||
|  | 	event_del(&ictx->timer); | ||||||
|  | 	event_add(&ictx->timer, &tv); | ||||||
|  | } | ||||||
|  |  | ||||||
| /* Reset cell state to default. */ | /* Reset cell state to default. */ | ||||||
| static void | static void | ||||||
| input_reset_cell(struct input_ctx *ictx) | input_reset_cell(struct input_ctx *ictx) | ||||||
| @@ -782,6 +809,8 @@ input_init(struct window_pane *wp) | |||||||
|  |  | ||||||
| 	ictx->since_ground = evbuffer_new(); | 	ictx->since_ground = evbuffer_new(); | ||||||
|  |  | ||||||
|  | 	evtimer_set(&ictx->timer, input_timer_callback, ictx); | ||||||
|  |  | ||||||
| 	input_reset(wp, 0); | 	input_reset(wp, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -791,6 +820,8 @@ input_free(struct window_pane *wp) | |||||||
| { | { | ||||||
| 	struct input_ctx	*ictx = wp->ictx; | 	struct input_ctx	*ictx = wp->ictx; | ||||||
|  |  | ||||||
|  | 	event_del(&ictx->timer); | ||||||
|  |  | ||||||
| 	free(ictx->input_buf); | 	free(ictx->input_buf); | ||||||
| 	evbuffer_free(ictx->since_ground); | 	evbuffer_free(ictx->since_ground); | ||||||
|  |  | ||||||
| @@ -815,14 +846,7 @@ input_reset(struct window_pane *wp, int clear) | |||||||
| 		screen_write_stop(&ictx->ctx); | 		screen_write_stop(&ictx->ctx); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	*ictx->interm_buf = '\0'; | 	input_clear(ictx); | ||||||
| 	ictx->interm_len = 0; |  | ||||||
|  |  | ||||||
| 	*ictx->param_buf = '\0'; |  | ||||||
| 	ictx->param_len = 0; |  | ||||||
|  |  | ||||||
| 	*ictx->input_buf = '\0'; |  | ||||||
| 	ictx->input_len = 0; |  | ||||||
|  |  | ||||||
| 	ictx->state = &input_state_ground; | 	ictx->state = &input_state_ground; | ||||||
| 	ictx->flags = 0; | 	ictx->flags = 0; | ||||||
| @@ -997,6 +1021,8 @@ input_reply(struct input_ctx *ictx, const char *fmt, ...) | |||||||
| static void | static void | ||||||
| input_clear(struct input_ctx *ictx) | input_clear(struct input_ctx *ictx) | ||||||
| { | { | ||||||
|  | 	event_del(&ictx->timer); | ||||||
|  |  | ||||||
| 	*ictx->interm_buf = '\0'; | 	*ictx->interm_buf = '\0'; | ||||||
| 	ictx->interm_len = 0; | 	ictx->interm_len = 0; | ||||||
|  |  | ||||||
| @@ -1013,6 +1039,7 @@ input_clear(struct input_ctx *ictx) | |||||||
| static void | static void | ||||||
| input_ground(struct input_ctx *ictx) | input_ground(struct input_ctx *ictx) | ||||||
| { | { | ||||||
|  | 	event_del(&ictx->timer); | ||||||
| 	evbuffer_drain(ictx->since_ground, EVBUFFER_LENGTH(ictx->since_ground)); | 	evbuffer_drain(ictx->since_ground, EVBUFFER_LENGTH(ictx->since_ground)); | ||||||
|  |  | ||||||
| 	if (ictx->input_space > INPUT_BUF_START) { | 	if (ictx->input_space > INPUT_BUF_START) { | ||||||
| @@ -1842,6 +1869,16 @@ input_csi_dispatch_sgr(struct input_ctx *ictx) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* DCS string started. */ | ||||||
|  | static void | ||||||
|  | input_enter_dcs(struct input_ctx *ictx) | ||||||
|  | { | ||||||
|  | 	log_debug("%s", __func__); | ||||||
|  |  | ||||||
|  | 	input_clear(ictx); | ||||||
|  | 	input_start_timer(ictx); | ||||||
|  | } | ||||||
|  |  | ||||||
| /* DCS terminator (ST) received. */ | /* DCS terminator (ST) received. */ | ||||||
| static int | static int | ||||||
| input_dcs_dispatch(struct input_ctx *ictx) | input_dcs_dispatch(struct input_ctx *ictx) | ||||||
| @@ -1871,6 +1908,7 @@ input_enter_osc(struct input_ctx *ictx) | |||||||
| 	log_debug("%s", __func__); | 	log_debug("%s", __func__); | ||||||
|  |  | ||||||
| 	input_clear(ictx); | 	input_clear(ictx); | ||||||
|  | 	input_start_timer(ictx); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* OSC terminator (ST) received. */ | /* OSC terminator (ST) received. */ | ||||||
| @@ -1937,6 +1975,7 @@ input_enter_apc(struct input_ctx *ictx) | |||||||
| 	log_debug("%s", __func__); | 	log_debug("%s", __func__); | ||||||
|  |  | ||||||
| 	input_clear(ictx); | 	input_clear(ictx); | ||||||
|  | 	input_start_timer(ictx); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* APC terminator (ST) received. */ | /* APC terminator (ST) received. */ | ||||||
| @@ -1960,6 +1999,7 @@ input_enter_rename(struct input_ctx *ictx) | |||||||
| 	log_debug("%s", __func__); | 	log_debug("%s", __func__); | ||||||
|  |  | ||||||
| 	input_clear(ictx); | 	input_clear(ictx); | ||||||
|  | 	input_start_timer(ictx); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Rename terminator (ST) received. */ | /* Rename terminator (ST) received. */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 nicm
					nicm