mirror of
https://github.com/tmux/tmux.git
synced 2024-10-31 22:58:49 +00:00
Don't use a bufferevent for the tty, so we can keep better track of what
is being written and when. Also a manpage typo fix from jmc@.
This commit is contained in:
parent
c6a3446398
commit
d22c15107b
2
tmux.1
2
tmux.1
@ -860,7 +860,7 @@ If
|
|||||||
is given, it specifies a
|
is given, it specifies a
|
||||||
.Ic session group .
|
.Ic session group .
|
||||||
Sessions in the same group share the same set of windows - new windows are
|
Sessions in the same group share the same set of windows - new windows are
|
||||||
linked to all sessions in the grouo and any windows closed removed from all
|
linked to all sessions in the group and any windows closed removed from all
|
||||||
sessions.
|
sessions.
|
||||||
The current and previous window and any session options remain independent and
|
The current and previous window and any session options remain independent and
|
||||||
any session in a group may be killed without affecting the others.
|
any session in a group may be killed without affecting the others.
|
||||||
|
5
tmux.h
5
tmux.h
@ -1041,7 +1041,10 @@ struct tty {
|
|||||||
u_int rright;
|
u_int rright;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
struct bufferevent *event;
|
struct event event_in;
|
||||||
|
struct evbuffer *in;
|
||||||
|
struct event event_out;
|
||||||
|
struct evbuffer *out;
|
||||||
|
|
||||||
struct termios tio;
|
struct termios tio;
|
||||||
|
|
||||||
|
@ -532,8 +532,8 @@ tty_keys_next(struct tty *tty)
|
|||||||
key_code key;
|
key_code key;
|
||||||
|
|
||||||
/* Get key buffer. */
|
/* Get key buffer. */
|
||||||
buf = EVBUFFER_DATA(tty->event->input);
|
buf = EVBUFFER_DATA(tty->in);
|
||||||
len = EVBUFFER_LENGTH(tty->event->input);
|
len = EVBUFFER_LENGTH(tty->in);
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return (0);
|
return (0);
|
||||||
@ -645,7 +645,7 @@ complete_key:
|
|||||||
key = (key & KEYC_MASK_MOD) | KEYC_BSPACE;
|
key = (key & KEYC_MASK_MOD) | KEYC_BSPACE;
|
||||||
|
|
||||||
/* Remove data from buffer. */
|
/* Remove data from buffer. */
|
||||||
evbuffer_drain(tty->event->input, size);
|
evbuffer_drain(tty->in, size);
|
||||||
|
|
||||||
/* Remove key timer. */
|
/* Remove key timer. */
|
||||||
if (event_initialized(&tty->key_timer))
|
if (event_initialized(&tty->key_timer))
|
||||||
@ -671,7 +671,7 @@ discard_key:
|
|||||||
log_debug("discard key %.*s %#llx", (int)size, buf, key);
|
log_debug("discard key %.*s %#llx", (int)size, buf, key);
|
||||||
|
|
||||||
/* Remove data from buffer. */
|
/* Remove data from buffer. */
|
||||||
evbuffer_drain(tty->event->input, size);
|
evbuffer_drain(tty->in, size);
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
121
tty.c
121
tty.c
@ -34,11 +34,6 @@
|
|||||||
|
|
||||||
static int tty_log_fd = -1;
|
static int tty_log_fd = -1;
|
||||||
|
|
||||||
static void tty_init_termios(int, struct termios *, struct bufferevent *);
|
|
||||||
|
|
||||||
static void tty_read_callback(struct bufferevent *, void *);
|
|
||||||
static void tty_error_callback(struct bufferevent *, short, void *);
|
|
||||||
|
|
||||||
static int tty_client_ready(struct client *, struct window_pane *);
|
static int tty_client_ready(struct client *, struct window_pane *);
|
||||||
|
|
||||||
static void tty_set_italics(struct tty *);
|
static void tty_set_italics(struct tty *);
|
||||||
@ -159,6 +154,38 @@ tty_set_size(struct tty *tty, u_int sx, u_int sy)
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tty_read_callback(__unused int fd, __unused short events, void *data)
|
||||||
|
{
|
||||||
|
struct tty *tty = data;
|
||||||
|
size_t size = EVBUFFER_LENGTH(tty->in);
|
||||||
|
int nread;
|
||||||
|
|
||||||
|
nread = evbuffer_read(tty->in, tty->fd, -1);
|
||||||
|
if (nread == -1)
|
||||||
|
return;
|
||||||
|
log_debug("%s: read %d bytes (already %zu)", tty->path, nread, size);
|
||||||
|
|
||||||
|
while (tty_keys_next(tty))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tty_write_callback(__unused int fd, __unused short events, void *data)
|
||||||
|
{
|
||||||
|
struct tty *tty = data;
|
||||||
|
size_t size = EVBUFFER_LENGTH(tty->out);
|
||||||
|
int nwrite;
|
||||||
|
|
||||||
|
nwrite = evbuffer_write(tty->out, tty->fd);
|
||||||
|
if (nwrite == -1)
|
||||||
|
return;
|
||||||
|
log_debug("%s: wrote %d bytes (of %zu)", tty->path, nwrite, size);
|
||||||
|
|
||||||
|
if (EVBUFFER_LENGTH(tty->out) == 0)
|
||||||
|
event_del(&tty->event_out);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
tty_open(struct tty *tty, char **cause)
|
tty_open(struct tty *tty, char **cause)
|
||||||
{
|
{
|
||||||
@ -169,10 +196,14 @@ tty_open(struct tty *tty, char **cause)
|
|||||||
}
|
}
|
||||||
tty->flags |= TTY_OPENED;
|
tty->flags |= TTY_OPENED;
|
||||||
|
|
||||||
tty->flags &= ~(TTY_NOCURSOR|TTY_FREEZE|TTY_TIMER);
|
tty->flags &= ~(TTY_NOCURSOR|TTY_FREEZE);
|
||||||
|
|
||||||
tty->event = bufferevent_new(tty->fd, tty_read_callback, NULL,
|
event_set(&tty->event_in, tty->fd, EV_PERSIST|EV_READ,
|
||||||
tty_error_callback, tty);
|
tty_read_callback, tty);
|
||||||
|
tty->in = evbuffer_new();
|
||||||
|
|
||||||
|
event_set(&tty->event_out, tty->fd, EV_WRITE, tty_write_callback, tty);
|
||||||
|
tty->out = evbuffer_new();
|
||||||
|
|
||||||
tty_start_tty(tty);
|
tty_start_tty(tty);
|
||||||
|
|
||||||
@ -181,50 +212,26 @@ tty_open(struct tty *tty, char **cause)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
tty_read_callback(__unused struct bufferevent *bufev, void *data)
|
|
||||||
{
|
|
||||||
struct tty *tty = data;
|
|
||||||
|
|
||||||
while (tty_keys_next(tty))
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
tty_error_callback(__unused struct bufferevent *bufev, __unused short what,
|
|
||||||
__unused void *data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
tty_init_termios(int fd, struct termios *orig_tio, struct bufferevent *bufev)
|
|
||||||
{
|
|
||||||
struct termios tio;
|
|
||||||
|
|
||||||
if (fd == -1 || tcgetattr(fd, orig_tio) != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
setblocking(fd, 0);
|
|
||||||
|
|
||||||
if (bufev != NULL)
|
|
||||||
bufferevent_enable(bufev, EV_READ|EV_WRITE);
|
|
||||||
|
|
||||||
memcpy(&tio, orig_tio, sizeof tio);
|
|
||||||
tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR|IGNCR|IMAXBEL|ISTRIP);
|
|
||||||
tio.c_iflag |= IGNBRK;
|
|
||||||
tio.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONLRET);
|
|
||||||
tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHONL|ECHOCTL|
|
|
||||||
ECHOPRT|ECHOKE|ISIG);
|
|
||||||
tio.c_cc[VMIN] = 1;
|
|
||||||
tio.c_cc[VTIME] = 0;
|
|
||||||
if (tcsetattr(fd, TCSANOW, &tio) == 0)
|
|
||||||
tcflush(fd, TCIOFLUSH);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_start_tty(struct tty *tty)
|
tty_start_tty(struct tty *tty)
|
||||||
{
|
{
|
||||||
tty_init_termios(tty->fd, &tty->tio, tty->event);
|
struct termios tio;
|
||||||
|
|
||||||
|
if (tty->fd != -1 && tcgetattr(tty->fd, &tty->tio) == 0) {
|
||||||
|
setblocking(tty->fd, 0);
|
||||||
|
event_add(&tty->event_in, NULL);
|
||||||
|
|
||||||
|
memcpy(&tio, &tty->tio, sizeof tio);
|
||||||
|
tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR|IGNCR|IMAXBEL|ISTRIP);
|
||||||
|
tio.c_iflag |= IGNBRK;
|
||||||
|
tio.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONLRET);
|
||||||
|
tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHONL|ECHOCTL|
|
||||||
|
ECHOPRT|ECHOKE|ISIG);
|
||||||
|
tio.c_cc[VMIN] = 1;
|
||||||
|
tio.c_cc[VTIME] = 0;
|
||||||
|
if (tcsetattr(tty->fd, TCSANOW, &tio) == 0)
|
||||||
|
tcflush(tty->fd, TCIOFLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
tty_putcode(tty, TTYC_SMCUP);
|
tty_putcode(tty, TTYC_SMCUP);
|
||||||
|
|
||||||
@ -264,7 +271,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);
|
event_del(&tty->event_in);
|
||||||
|
event_del(&tty->event_out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Be flexible about error handling and try not kill the server just
|
* Be flexible about error handling and try not kill the server just
|
||||||
@ -318,7 +326,10 @@ 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);
|
evbuffer_free(tty->in);
|
||||||
|
event_del(&tty->event_in);
|
||||||
|
evbuffer_free(tty->out);
|
||||||
|
event_del(&tty->event_out);
|
||||||
|
|
||||||
tty_term_free(tty->term);
|
tty_term_free(tty->term);
|
||||||
tty_keys_free(tty);
|
tty_keys_free(tty);
|
||||||
@ -411,11 +422,13 @@ tty_putcode_ptr2(struct tty *tty, enum tty_code_code code, const void *a,
|
|||||||
static void
|
static void
|
||||||
tty_add(struct tty *tty, const char *buf, size_t len)
|
tty_add(struct tty *tty, const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
bufferevent_write(tty->event, buf, len);
|
evbuffer_add(tty->out, buf, len);
|
||||||
log_debug("%s: %.*s", tty->path, (int)len, buf);
|
log_debug("%s: %.*s", tty->path, (int)len, (const char *)buf);
|
||||||
|
|
||||||
if (tty_log_fd != -1)
|
if (tty_log_fd != -1)
|
||||||
write(tty_log_fd, buf, len);
|
write(tty_log_fd, buf, len);
|
||||||
|
if (tty->flags & TTY_STARTED)
|
||||||
|
event_add(&tty->event_out, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -730,7 +743,7 @@ tty_client_ready(struct client *c, struct window_pane *wp)
|
|||||||
{
|
{
|
||||||
if (c->session == NULL || c->tty.term == NULL)
|
if (c->session == NULL || c->tty.term == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
if (c->flags & CLIENT_SUSPENDED)
|
if (c->flags & (CLIENT_REDRAW|CLIENT_SUSPENDED))
|
||||||
return (0);
|
return (0);
|
||||||
if (c->tty.flags & TTY_FREEZE)
|
if (c->tty.flags & TTY_FREEZE)
|
||||||
return (0);
|
return (0);
|
||||||
|
Loading…
Reference in New Issue
Block a user