mirror of
https://github.com/tmux/tmux.git
synced 2025-01-13 03:48:51 +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:
parent
467ece53e6
commit
c5b7faaefc
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. */
|
||||||
|
Loading…
Reference in New Issue
Block a user