mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +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:
		
							
								
								
									
										121
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								tty.c
									
									
									
									
									
								
							@@ -34,11 +34,6 @@
 | 
			
		||||
 | 
			
		||||
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 void	tty_set_italics(struct tty *);
 | 
			
		||||
@@ -159,6 +154,38 @@ tty_set_size(struct tty *tty, u_int sx, u_int sy)
 | 
			
		||||
	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
 | 
			
		||||
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_NOCURSOR|TTY_FREEZE|TTY_TIMER);
 | 
			
		||||
	tty->flags &= ~(TTY_NOCURSOR|TTY_FREEZE);
 | 
			
		||||
 | 
			
		||||
	tty->event = bufferevent_new(tty->fd, tty_read_callback, NULL,
 | 
			
		||||
	    tty_error_callback, tty);
 | 
			
		||||
	event_set(&tty->event_in, tty->fd, EV_PERSIST|EV_READ,
 | 
			
		||||
	    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);
 | 
			
		||||
 | 
			
		||||
@@ -181,50 +212,26 @@ tty_open(struct tty *tty, char **cause)
 | 
			
		||||
	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
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
@@ -264,7 +271,8 @@ tty_stop_tty(struct tty *tty)
 | 
			
		||||
		return;
 | 
			
		||||
	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
 | 
			
		||||
@@ -318,7 +326,10 @@ tty_close(struct tty *tty)
 | 
			
		||||
	tty_stop_tty(tty);
 | 
			
		||||
 | 
			
		||||
	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_keys_free(tty);
 | 
			
		||||
@@ -411,11 +422,13 @@ tty_putcode_ptr2(struct tty *tty, enum tty_code_code code, const void *a,
 | 
			
		||||
static void
 | 
			
		||||
tty_add(struct tty *tty, const char *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	bufferevent_write(tty->event, buf, len);
 | 
			
		||||
	log_debug("%s: %.*s", tty->path, (int)len, buf);
 | 
			
		||||
	evbuffer_add(tty->out, buf, len);
 | 
			
		||||
	log_debug("%s: %.*s", tty->path, (int)len, (const char *)buf);
 | 
			
		||||
 | 
			
		||||
	if (tty_log_fd != -1)
 | 
			
		||||
		write(tty_log_fd, buf, len);
 | 
			
		||||
	if (tty->flags & TTY_STARTED)
 | 
			
		||||
		event_add(&tty->event_out, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -730,7 +743,7 @@ tty_client_ready(struct client *c, struct window_pane *wp)
 | 
			
		||||
{
 | 
			
		||||
	if (c->session == NULL || c->tty.term == NULL)
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (c->flags & CLIENT_SUSPENDED)
 | 
			
		||||
	if (c->flags & (CLIENT_REDRAW|CLIENT_SUSPENDED))
 | 
			
		||||
		return (0);
 | 
			
		||||
	if (c->tty.flags & TTY_FREEZE)
 | 
			
		||||
		return (0);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user