Switch tty fds over to a bufferevent.

pull/1/head
Nicholas Marriott 2009-11-04 21:47:42 +00:00
parent abb728684b
commit 7342615c7d
5 changed files with 38 additions and 45 deletions

View File

@ -136,7 +136,6 @@ server_client_lost(struct client *c)
close(c->ibuf.fd); close(c->ibuf.fd);
imsg_clear(&c->ibuf); imsg_clear(&c->ibuf);
event_del(&c->event); event_del(&c->event);
event_del(&c->tty.event);
for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) { for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) {
if (ARRAY_ITEM(&dead_clients, i) == NULL) { if (ARRAY_ITEM(&dead_clients, i) == NULL) {
@ -172,18 +171,6 @@ server_client_prepare(void)
event_set(&c->event, event_set(&c->event,
c->ibuf.fd, events, server_client_callback, c); c->ibuf.fd, events, server_client_callback, c);
event_add(&c->event, NULL); event_add(&c->event, NULL);
if (c->tty.fd == -1)
continue;
if (c->flags & CLIENT_SUSPENDED || c->session == NULL)
continue;
events = EV_READ;
if (BUFFER_USED(c->tty.out) > 0)
events |= EV_WRITE;
event_del(&c->tty.event);
event_set(&c->tty.event,
c->tty.fd, events, server_client_callback, c);
event_add(&c->tty.event, NULL);
} }
} }
@ -210,14 +197,6 @@ server_client_callback(int fd, short events, void *data)
goto client_lost; goto client_lost;
} }
if (c->tty.fd != -1 && fd == c->tty.fd) {
if (c->flags & CLIENT_SUSPENDED || c->session == NULL)
return;
if (buffer_poll(fd, events, c->tty.in, c->tty.out) != 0)
goto client_lost;
}
return; return;
client_lost: client_lost:

View File

@ -87,7 +87,8 @@ server_window_backoff(struct window_pane *wp)
continue; continue;
if (c->session->curw->window != wp->window) if (c->session->curw->window != wp->window)
continue; continue;
if (BUFFER_USED(c->tty.out) > BACKOFF_THRESHOLD)
if (EVBUFFER_LENGTH(c->tty.event->output) > BACKOFF_THRESHOLD)
return (1); return (1);
} }
return (0); return (0);

4
tmux.h
View File

@ -1000,9 +1000,7 @@ struct tty {
struct tty_term *term; struct tty_term *term;
int fd; int fd;
struct event event; struct bufferevent *event;
struct buffer *in;
struct buffer *out;
int log_fd; int log_fd;

View File

@ -299,18 +299,20 @@ tty_keys_next(struct tty *tty, int *key, struct mouse_event *mouse)
struct tty_key *tk; struct tty_key *tk;
struct timeval tv; struct timeval tv;
char *buf; char *buf;
u_char ch;
size_t len, size; size_t len, size;
cc_t bspace; cc_t bspace;
buf = BUFFER_OUT(tty->in); buf = EVBUFFER_DATA(tty->event->input);
len = BUFFER_USED(tty->in); len = EVBUFFER_LENGTH(tty->event->input);
if (len == 0) if (len == 0)
return (1); return (1);
log_debug("keys are %zu (%.*s)", len, (int) len, buf); log_debug("keys are %zu (%.*s)", len, (int) len, buf);
/* If a normal key, return it. */ /* If a normal key, return it. */
if (*buf != '\033') { if (*buf != '\033') {
*key = buffer_read8(tty->in); bufferevent_read(tty->event, &ch, 1);
*key = ch;
/* /*
* Check for backspace key using termios VERASE - the terminfo * Check for backspace key using termios VERASE - the terminfo
@ -326,7 +328,7 @@ tty_keys_next(struct tty *tty, int *key, struct mouse_event *mouse)
/* Look for matching key string and return if found. */ /* Look for matching key string and return if found. */
tk = tty_keys_find(tty, buf + 1, len - 1, &size); tk = tty_keys_find(tty, buf + 1, len - 1, &size);
if (tk != NULL) { if (tk != NULL) {
buffer_remove(tty->in, size + 1); evbuffer_drain(tty->event->input, size + 1);
*key = tk->key; *key = tk->key;
goto found; goto found;
} }
@ -334,14 +336,14 @@ tty_keys_next(struct tty *tty, int *key, struct mouse_event *mouse)
/* Not found. Is this a mouse key press? */ /* Not found. Is this a mouse key press? */
*key = tty_keys_mouse(buf, len, &size, mouse); *key = tty_keys_mouse(buf, len, &size, mouse);
if (*key != KEYC_NONE) { if (*key != KEYC_NONE) {
buffer_remove(tty->in, size); evbuffer_drain(tty->event->input, size);
goto found; goto found;
} }
/* Not found. Try to parse a key with an xterm-style modifier. */ /* Not found. Try to parse a key with an xterm-style modifier. */
*key = xterm_keys_find(buf, len, &size); *key = xterm_keys_find(buf, len, &size);
if (*key != KEYC_NONE) { if (*key != KEYC_NONE) {
buffer_remove(tty->in, size); evbuffer_drain(tty->event->input, size);
goto found; goto found;
} }
@ -363,8 +365,9 @@ tty_keys_next(struct tty *tty, int *key, struct mouse_event *mouse)
/* Is there a normal key following? */ /* Is there a normal key following? */
if (len != 0 && *buf != '\033') { if (len != 0 && *buf != '\033') {
buffer_remove(tty->in, 1); evbuffer_drain(tty->event->input, 1);
*key = buffer_read8(tty->in) | KEYC_ESCAPE; bufferevent_read(tty->event, &ch, 1);
*key = ch | KEYC_ESCAPE;
goto found; goto found;
} }
@ -372,7 +375,7 @@ tty_keys_next(struct tty *tty, int *key, struct mouse_event *mouse)
if (len > 1) { if (len > 1) {
tk = tty_keys_find(tty, buf + 1, len - 1, &size); tk = tty_keys_find(tty, buf + 1, len - 1, &size);
if (tk != NULL) { if (tk != NULL) {
buffer_remove(tty->in, size + 2); evbuffer_drain(tty->event->input, size + 2);
*key = tk->key | KEYC_ESCAPE; *key = tk->key | KEYC_ESCAPE;
goto found; goto found;
} }
@ -385,7 +388,7 @@ tty_keys_next(struct tty *tty, int *key, struct mouse_event *mouse)
return (1); return (1);
/* Give up and return the escape. */ /* Give up and return the escape. */
buffer_remove(tty->in, 1); evbuffer_drain(tty->event->input, 1);
*key = '\033'; *key = '\033';
found: found:

30
tty.c
View File

@ -28,6 +28,8 @@
#include "tmux.h" #include "tmux.h"
void tty_error_callback(struct bufferevent *, short, void *);
void tty_fill_acs(struct tty *); void tty_fill_acs(struct tty *);
int tty_try_256(struct tty *, u_char, const char *); int tty_try_256(struct tty *, u_char, const char *);
@ -108,11 +110,11 @@ tty_open(struct tty *tty, const char *overrides, char **cause)
} }
tty->flags |= TTY_OPENED; tty->flags |= TTY_OPENED;
tty->in = buffer_create(BUFSIZ);
tty->out = buffer_create(BUFSIZ);
tty->flags &= ~(TTY_NOCURSOR|TTY_FREEZE|TTY_ESCAPE); tty->flags &= ~(TTY_NOCURSOR|TTY_FREEZE|TTY_ESCAPE);
tty->event = bufferevent_new(
tty->fd, NULL, NULL, tty_error_callback, tty);
tty_start_tty(tty); tty_start_tty(tty);
tty_keys_init(tty); tty_keys_init(tty);
@ -122,6 +124,13 @@ tty_open(struct tty *tty, const char *overrides, char **cause)
return (0); return (0);
} }
void
tty_error_callback(
unused struct bufferevent *bufev, unused short what, unused void *data)
{
fatalx("lost terminal");
}
void void
tty_start_tty(struct tty *tty) tty_start_tty(struct tty *tty)
{ {
@ -136,6 +145,8 @@ tty_start_tty(struct tty *tty)
if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1) if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1)
fatal("fcntl failed"); fatal("fcntl failed");
bufferevent_enable(tty->event, EV_READ|EV_WRITE);
if (tcgetattr(tty->fd, &tty->tio) != 0) if (tcgetattr(tty->fd, &tty->tio) != 0)
fatal("tcgetattr failed"); fatal("tcgetattr failed");
memcpy(&tio, &tty->tio, sizeof tio); memcpy(&tio, &tty->tio, sizeof tio);
@ -187,6 +198,8 @@ tty_stop_tty(struct tty *tty)
return; return;
tty->flags &= ~TTY_STARTED; tty->flags &= ~TTY_STARTED;
bufferevent_disable(tty->event, EV_READ|EV_WRITE);
/* /*
* Be flexible about error handling and try not kill the server just * Be flexible about error handling and try not kill the server just
* because the fd is invalid. Things like ssh -t can easily leave us * because the fd is invalid. Things like ssh -t can easily leave us
@ -249,12 +262,11 @@ tty_close(struct tty *tty)
tty_stop_tty(tty); tty_stop_tty(tty);
if (tty->flags & TTY_OPENED) { if (tty->flags & TTY_OPENED) {
bufferevent_free(tty->event);
tty_term_free(tty->term); tty_term_free(tty->term);
tty_keys_free(tty); tty_keys_free(tty);
buffer_destroy(tty->in);
buffer_destroy(tty->out);
tty->flags &= ~TTY_OPENED; tty->flags &= ~TTY_OPENED;
} }
@ -308,7 +320,7 @@ tty_puts(struct tty *tty, const char *s)
{ {
if (*s == '\0') if (*s == '\0')
return; return;
buffer_write(tty->out, s, strlen(s)); bufferevent_write(tty->event, s, strlen(s));
if (tty->log_fd != -1) if (tty->log_fd != -1)
write(tty->log_fd, s, strlen(s)); write(tty->log_fd, s, strlen(s));
@ -321,7 +333,7 @@ tty_putc(struct tty *tty, u_char ch)
if (tty->cell.attr & GRID_ATTR_CHARSET) if (tty->cell.attr & GRID_ATTR_CHARSET)
ch = tty_get_acs(tty, ch); ch = tty_get_acs(tty, ch);
buffer_write8(tty->out, ch); bufferevent_write(tty->event, &ch, 1);
if (ch >= 0x20 && ch != 0x7f) { if (ch >= 0x20 && ch != 0x7f) {
sx = tty->sx; sx = tty->sx;
@ -348,7 +360,7 @@ tty_pututf8(struct tty *tty, const struct grid_utf8 *gu)
for (i = 0; i < UTF8_SIZE; i++) { for (i = 0; i < UTF8_SIZE; i++) {
if (gu->data[i] == 0xff) if (gu->data[i] == 0xff)
break; break;
buffer_write8(tty->out, gu->data[i]); bufferevent_write(tty->event, &gu->data[i], 1);
if (tty->log_fd != -1) if (tty->log_fd != -1)
write(tty->log_fd, &gu->data[i], 1); write(tty->log_fd, &gu->data[i], 1);
} }