summaryrefslogtreecommitdiff
path: root/usr.bin/tmux
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2017-06-04 09:22:35 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2017-06-04 09:22:35 +0000
commitedf0e0fa4f7212ddfc593fc314df7ed0ef6f0bf4 (patch)
treef806f175f4d9830f5d8c5a7e54b173455892db96 /usr.bin/tmux
parentbcc29bdae3b156a444ed837eeb8ab35eeb068919 (diff)
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.
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r--usr.bin/tmux/input.c60
1 files changed, 50 insertions, 10 deletions
diff --git a/usr.bin/tmux/input.c b/usr.bin/tmux/input.c
index e6ea4c95feb..9359acb2a2b 100644
--- a/usr.bin/tmux/input.c
+++ b/usr.bin/tmux/input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: input.c,v 1.124 2017/06/04 09:02:36 nicm Exp $ */
+/* $OpenBSD: input.c,v 1.125 2017/06/04 09:22:34 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -93,6 +93,8 @@ struct input_ctx {
const struct input_state *state;
+ struct event timer;
+
/*
* All input received since we were last in the ground state. Sent to
* control clients on connection.
@@ -118,6 +120,7 @@ static void input_osc_104(struct window_pane *, const char *);
/* Transition entry/exit handlers. */
static void input_clear(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_exit_osc(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. */
static const struct input_state input_state_dcs_enter = {
"dcs_enter",
- input_clear, NULL,
+ input_enter_dcs, NULL,
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));
}
+/*
+ * 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. */
static void
input_reset_cell(struct input_ctx *ictx)
@@ -782,6 +809,8 @@ input_init(struct window_pane *wp)
ictx->since_ground = evbuffer_new();
+ evtimer_set(&ictx->timer, input_timer_callback, ictx);
+
input_reset(wp, 0);
}
@@ -791,6 +820,8 @@ input_free(struct window_pane *wp)
{
struct input_ctx *ictx = wp->ictx;
+ event_del(&ictx->timer);
+
free(ictx->input_buf);
evbuffer_free(ictx->since_ground);
@@ -815,14 +846,7 @@ input_reset(struct window_pane *wp, int clear)
screen_write_stop(&ictx->ctx);
}
- *ictx->interm_buf = '\0';
- ictx->interm_len = 0;
-
- *ictx->param_buf = '\0';
- ictx->param_len = 0;
-
- *ictx->input_buf = '\0';
- ictx->input_len = 0;
+ input_clear(ictx);
ictx->state = &input_state_ground;
ictx->flags = 0;
@@ -997,6 +1021,8 @@ input_reply(struct input_ctx *ictx, const char *fmt, ...)
static void
input_clear(struct input_ctx *ictx)
{
+ event_del(&ictx->timer);
+
*ictx->interm_buf = '\0';
ictx->interm_len = 0;
@@ -1013,6 +1039,7 @@ input_clear(struct input_ctx *ictx)
static void
input_ground(struct input_ctx *ictx)
{
+ event_del(&ictx->timer);
evbuffer_drain(ictx->since_ground, EVBUFFER_LENGTH(ictx->since_ground));
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. */
static int
input_dcs_dispatch(struct input_ctx *ictx)
@@ -1871,6 +1908,7 @@ input_enter_osc(struct input_ctx *ictx)
log_debug("%s", __func__);
input_clear(ictx);
+ input_start_timer(ictx);
}
/* OSC terminator (ST) received. */
@@ -1937,6 +1975,7 @@ input_enter_apc(struct input_ctx *ictx)
log_debug("%s", __func__);
input_clear(ictx);
+ input_start_timer(ictx);
}
/* APC terminator (ST) received. */
@@ -1960,6 +1999,7 @@ input_enter_rename(struct input_ctx *ictx)
log_debug("%s", __func__);
input_clear(ictx);
+ input_start_timer(ictx);
}
/* Rename terminator (ST) received. */