mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
This commit is contained in:
		| @@ -165,13 +165,13 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) | |||||||
| 	 * the terminal as that calls tcsetattr() to prepare for tmux taking | 	 * the terminal as that calls tcsetattr() to prepare for tmux taking | ||||||
| 	 * over. | 	 * over. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (!detached && !already_attached && c->tty.fd != -1) { | 	if (!detached && !already_attached && c->fd != -1) { | ||||||
| 		if (server_client_check_nested(cmdq_get_client(item))) { | 		if (server_client_check_nested(cmdq_get_client(item))) { | ||||||
| 			cmdq_error(item, "sessions should be nested with care, " | 			cmdq_error(item, "sessions should be nested with care, " | ||||||
| 			    "unset $TMUX to force"); | 			    "unset $TMUX to force"); | ||||||
| 			goto fail; | 			goto fail; | ||||||
| 		} | 		} | ||||||
| 		if (tcgetattr(c->tty.fd, &tio) != 0) | 		if (tcgetattr(c->fd, &tio) != 0) | ||||||
| 			fatal("tcgetattr failed"); | 			fatal("tcgetattr failed"); | ||||||
| 		tiop = &tio; | 		tiop = &tio; | ||||||
| 	} else | 	} else | ||||||
|   | |||||||
							
								
								
									
										43
									
								
								control.c
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								control.c
									
									
									
									
									
								
							| @@ -38,6 +38,11 @@ struct control_offset { | |||||||
| }; | }; | ||||||
| RB_HEAD(control_offsets, control_offset); | RB_HEAD(control_offsets, control_offset); | ||||||
|  |  | ||||||
|  | /* Control state. */ | ||||||
|  | struct control_state { | ||||||
|  | 	struct control_offsets	offsets; | ||||||
|  | }; | ||||||
|  |  | ||||||
| /* Compare client offsets. */ | /* Compare client offsets. */ | ||||||
| static int | static int | ||||||
| control_offset_cmp(struct control_offset *co1, struct control_offset *co2) | control_offset_cmp(struct control_offset *co1, struct control_offset *co2) | ||||||
| @@ -54,31 +59,26 @@ RB_GENERATE_STATIC(control_offsets, control_offset, entry, control_offset_cmp); | |||||||
| static struct control_offset * | static struct control_offset * | ||||||
| control_get_offset(struct client *c, struct window_pane *wp) | control_get_offset(struct client *c, struct window_pane *wp) | ||||||
| { | { | ||||||
| 	struct control_offset	co = { .pane = wp->id }; | 	struct control_state	*cs = c->control_state; | ||||||
|  | 	struct control_offset	 co = { .pane = wp->id }; | ||||||
|  |  | ||||||
| 	if (c->offsets == NULL) | 	return (RB_FIND(control_offsets, &cs->offsets, &co)); | ||||||
| 		return (NULL); |  | ||||||
| 	return (RB_FIND(control_offsets, c->offsets, &co)); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Add pane offsets for this client. */ | /* Add pane offsets for this client. */ | ||||||
| static struct control_offset * | static struct control_offset * | ||||||
| control_add_offset(struct client *c, struct window_pane *wp) | control_add_offset(struct client *c, struct window_pane *wp) | ||||||
| { | { | ||||||
|  | 	struct control_state	*cs = c->control_state; | ||||||
| 	struct control_offset	*co; | 	struct control_offset	*co; | ||||||
|  |  | ||||||
| 	co = control_get_offset(c, wp); | 	co = control_get_offset(c, wp); | ||||||
| 	if (co != NULL) | 	if (co != NULL) | ||||||
| 		return (co); | 		return (co); | ||||||
|  |  | ||||||
| 	if (c->offsets == NULL) { |  | ||||||
| 		c->offsets = xmalloc(sizeof *c->offsets); |  | ||||||
| 		RB_INIT(c->offsets); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	co = xcalloc(1, sizeof *co); | 	co = xcalloc(1, sizeof *co); | ||||||
| 	co->pane = wp->id; | 	co->pane = wp->id; | ||||||
| 	RB_INSERT(control_offsets, c->offsets, co); | 	RB_INSERT(control_offsets, &cs->offsets, co); | ||||||
| 	memcpy(&co->offset, &wp->offset, sizeof co->offset); | 	memcpy(&co->offset, &wp->offset, sizeof co->offset); | ||||||
| 	return (co); | 	return (co); | ||||||
| } | } | ||||||
| @@ -87,15 +87,13 @@ control_add_offset(struct client *c, struct window_pane *wp) | |||||||
| void | void | ||||||
| control_free_offsets(struct client *c) | control_free_offsets(struct client *c) | ||||||
| { | { | ||||||
|  | 	struct control_state	*cs = c->control_state; | ||||||
| 	struct control_offset	*co, *co1; | 	struct control_offset	*co, *co1; | ||||||
|  |  | ||||||
| 	if (c->offsets == NULL) | 	RB_FOREACH_SAFE(co, control_offsets, &cs->offsets, co1) { | ||||||
| 		return; | 		RB_REMOVE(control_offsets, &cs->offsets, co); | ||||||
| 	RB_FOREACH_SAFE(co, control_offsets, c->offsets, co1) { |  | ||||||
| 		RB_REMOVE(control_offsets, c->offsets, co); |  | ||||||
| 		free(co); | 		free(co); | ||||||
| 	} | 	} | ||||||
| 	free(c->offsets); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Get offsets for client. */ | /* Get offsets for client. */ | ||||||
| @@ -255,8 +253,23 @@ control_callback(__unused struct client *c, __unused const char *path, | |||||||
| void | void | ||||||
| control_start(struct client *c) | control_start(struct client *c) | ||||||
| { | { | ||||||
|  | 	struct control_state	*cs; | ||||||
|  |  | ||||||
|  | 	cs = c->control_state = xcalloc(1, sizeof *cs); | ||||||
|  | 	RB_INIT(&cs->offsets); | ||||||
|  |  | ||||||
| 	file_read(c, "-", control_callback, c); | 	file_read(c, "-", control_callback, c); | ||||||
|  |  | ||||||
| 	if (c->flags & CLIENT_CONTROLCONTROL) | 	if (c->flags & CLIENT_CONTROLCONTROL) | ||||||
| 		file_print(c, "\033P1000p"); | 		file_print(c, "\033P1000p"); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* Stop control mode. */ | ||||||
|  | void | ||||||
|  | control_stop(struct client *c) | ||||||
|  | { | ||||||
|  | 	struct control_state	*cs = c->control_state; | ||||||
|  |  | ||||||
|  | 	control_free_offsets(c); | ||||||
|  | 	free(cs); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -227,7 +227,6 @@ server_client_create(int fd) | |||||||
| 	RB_INIT(&c->windows); | 	RB_INIT(&c->windows); | ||||||
| 	RB_INIT(&c->files); | 	RB_INIT(&c->files); | ||||||
|  |  | ||||||
| 	c->tty.fd = -1; |  | ||||||
| 	c->tty.sx = 80; | 	c->tty.sx = 80; | ||||||
| 	c->tty.sy = 24; | 	c->tty.sy = 24; | ||||||
|  |  | ||||||
| @@ -305,10 +304,8 @@ server_client_lost(struct client *c) | |||||||
| 	TAILQ_REMOVE(&clients, c, entry); | 	TAILQ_REMOVE(&clients, c, entry); | ||||||
| 	log_debug("lost client %p", c); | 	log_debug("lost client %p", c); | ||||||
|  |  | ||||||
| 	/* | 	if (c->flags & CLIENT_CONTROL) | ||||||
| 	 * If CLIENT_TERMINAL hasn't been set, then tty_init hasn't been called | 		control_stop(c); | ||||||
| 	 * and tty_free might close an unrelated fd. |  | ||||||
| 	 */ |  | ||||||
| 	if (c->flags & CLIENT_TERMINAL) | 	if (c->flags & CLIENT_TERMINAL) | ||||||
| 		tty_free(&c->tty); | 		tty_free(&c->tty); | ||||||
| 	free(c->ttyname); | 	free(c->ttyname); | ||||||
| @@ -340,6 +337,10 @@ server_client_lost(struct client *c) | |||||||
| 	proc_remove_peer(c->peer); | 	proc_remove_peer(c->peer); | ||||||
| 	c->peer = NULL; | 	c->peer = NULL; | ||||||
|  |  | ||||||
|  | 	if (c->fd != -1) { | ||||||
|  | 		close(c->fd); | ||||||
|  | 		c->fd = -1; | ||||||
|  | 	} | ||||||
| 	server_client_unref(c); | 	server_client_unref(c); | ||||||
|  |  | ||||||
| 	server_add_accept(0); /* may be more file descriptors now */ | 	server_add_accept(0); /* may be more file descriptors now */ | ||||||
| @@ -2006,7 +2007,7 @@ server_client_dispatch(struct imsg *imsg, void *arg) | |||||||
| 			break; | 			break; | ||||||
| 		c->flags &= ~CLIENT_SUSPENDED; | 		c->flags &= ~CLIENT_SUSPENDED; | ||||||
|  |  | ||||||
| 		if (c->tty.fd == -1) /* exited in the meantime */ | 		if (c->fd == -1) /* exited in the meantime */ | ||||||
| 			break; | 			break; | ||||||
| 		s = c->session; | 		s = c->session; | ||||||
|  |  | ||||||
| @@ -2212,11 +2213,9 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg) | |||||||
| 	if (c->flags & CLIENT_CONTROL) { | 	if (c->flags & CLIENT_CONTROL) { | ||||||
| 		close(c->fd); | 		close(c->fd); | ||||||
| 		c->fd = -1; | 		c->fd = -1; | ||||||
|  |  | ||||||
| 		control_start(c); | 		control_start(c); | ||||||
| 		c->tty.fd = -1; |  | ||||||
| 	} else if (c->fd != -1) { | 	} else if (c->fd != -1) { | ||||||
| 		if (tty_init(&c->tty, c, c->fd) != 0) { | 		if (tty_init(&c->tty, c) != 0) { | ||||||
| 			close(c->fd); | 			close(c->fd); | ||||||
| 			c->fd = -1; | 			c->fd = -1; | ||||||
| 		} else { | 		} else { | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -47,7 +47,7 @@ struct cmdq_item; | |||||||
| struct cmdq_list; | struct cmdq_list; | ||||||
| struct cmdq_state; | struct cmdq_state; | ||||||
| struct cmds; | struct cmds; | ||||||
| struct control_offsets; | struct control_state; | ||||||
| struct environ; | struct environ; | ||||||
| struct format_job_tree; | struct format_job_tree; | ||||||
| struct format_tree; | struct format_tree; | ||||||
| @@ -1285,7 +1285,6 @@ struct tty { | |||||||
| 	u_int		 rleft; | 	u_int		 rleft; | ||||||
| 	u_int		 rright; | 	u_int		 rright; | ||||||
|  |  | ||||||
| 	int		 fd; |  | ||||||
| 	struct event	 event_in; | 	struct event	 event_in; | ||||||
| 	struct evbuffer	*in; | 	struct evbuffer	*in; | ||||||
| 	struct event	 event_out; | 	struct event	 event_out; | ||||||
| @@ -1566,7 +1565,7 @@ struct client { | |||||||
| 	struct cmdq_list *queue; | 	struct cmdq_list *queue; | ||||||
|  |  | ||||||
| 	struct client_windows windows; | 	struct client_windows windows; | ||||||
| 	struct control_offsets *offsets; | 	struct control_state *control_state; | ||||||
|  |  | ||||||
| 	pid_t		 pid; | 	pid_t		 pid; | ||||||
| 	int		 fd; | 	int		 fd; | ||||||
| @@ -2066,7 +2065,7 @@ void	tty_putc(struct tty *, u_char); | |||||||
| void	tty_putn(struct tty *, const void *, size_t, u_int); | void	tty_putn(struct tty *, const void *, size_t, u_int); | ||||||
| void	tty_cell(struct tty *, const struct grid_cell *, | void	tty_cell(struct tty *, const struct grid_cell *, | ||||||
| 	    const struct grid_cell *, int *); | 	    const struct grid_cell *, int *); | ||||||
| int	tty_init(struct tty *, struct client *, int); | int	tty_init(struct tty *, struct client *); | ||||||
| void	tty_resize(struct tty *); | void	tty_resize(struct tty *); | ||||||
| void	tty_set_size(struct tty *, u_int, u_int, u_int, u_int); | void	tty_set_size(struct tty *, u_int, u_int, u_int, u_int); | ||||||
| void	tty_start_tty(struct tty *); | void	tty_start_tty(struct tty *); | ||||||
| @@ -2816,6 +2815,7 @@ char	*parse_window_name(const char *); | |||||||
|  |  | ||||||
| /* control.c */ | /* control.c */ | ||||||
| void	control_start(struct client *); | void	control_start(struct client *); | ||||||
|  | void	control_stop(struct client *); | ||||||
| void	control_set_pane_on(struct client *, struct window_pane *); | void	control_set_pane_on(struct client *, struct window_pane *); | ||||||
| void	control_set_pane_off(struct client *, struct window_pane *); | void	control_set_pane_off(struct client *, struct window_pane *); | ||||||
| struct window_pane_offset *control_pane_offset(struct client *, | struct window_pane_offset *control_pane_offset(struct client *, | ||||||
|   | |||||||
							
								
								
									
										67
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								tty.c
									
									
									
									
									
								
							| @@ -90,19 +90,19 @@ tty_create_log(void) | |||||||
| } | } | ||||||
|  |  | ||||||
| int | int | ||||||
| tty_init(struct tty *tty, struct client *c, int fd) | tty_init(struct tty *tty, struct client *c) | ||||||
| { | { | ||||||
| 	if (!isatty(fd)) | 	if (!isatty(c->fd)) | ||||||
| 		return (-1); | 		return (-1); | ||||||
|  |  | ||||||
| 	memset(tty, 0, sizeof *tty); | 	memset(tty, 0, sizeof *tty); | ||||||
|  |  | ||||||
| 	tty->fd = fd; |  | ||||||
| 	tty->client = c; | 	tty->client = c; | ||||||
|  |  | ||||||
| 	tty->cstyle = 0; | 	tty->cstyle = 0; | ||||||
| 	tty->ccolour = xstrdup(""); | 	tty->ccolour = xstrdup(""); | ||||||
|  |  | ||||||
|  | 	if (tcgetattr(c->fd, &tty->tio) != 0) | ||||||
|  | 		return (-1); | ||||||
| 	return (0); | 	return (0); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -113,7 +113,7 @@ tty_resize(struct tty *tty) | |||||||
| 	struct winsize	 ws; | 	struct winsize	 ws; | ||||||
| 	u_int		 sx, sy, xpixel, ypixel; | 	u_int		 sx, sy, xpixel, ypixel; | ||||||
|  |  | ||||||
| 	if (ioctl(tty->fd, TIOCGWINSZ, &ws) != -1) { | 	if (ioctl(c->fd, TIOCGWINSZ, &ws) != -1) { | ||||||
| 		sx = ws.ws_col; | 		sx = ws.ws_col; | ||||||
| 		if (sx == 0) { | 		if (sx == 0) { | ||||||
| 			sx = 80; | 			sx = 80; | ||||||
| @@ -156,7 +156,7 @@ tty_read_callback(__unused int fd, __unused short events, void *data) | |||||||
| 	size_t		 size = EVBUFFER_LENGTH(tty->in); | 	size_t		 size = EVBUFFER_LENGTH(tty->in); | ||||||
| 	int		 nread; | 	int		 nread; | ||||||
|  |  | ||||||
| 	nread = evbuffer_read(tty->in, tty->fd, -1); | 	nread = evbuffer_read(tty->in, c->fd, -1); | ||||||
| 	if (nread == 0 || nread == -1) { | 	if (nread == 0 || nread == -1) { | ||||||
| 		if (nread == 0) | 		if (nread == 0) | ||||||
| 			log_debug("%s: read closed", name); | 			log_debug("%s: read closed", name); | ||||||
| @@ -225,7 +225,7 @@ tty_write_callback(__unused int fd, __unused short events, void *data) | |||||||
| 	size_t		 size = EVBUFFER_LENGTH(tty->out); | 	size_t		 size = EVBUFFER_LENGTH(tty->out); | ||||||
| 	int		 nwrite; | 	int		 nwrite; | ||||||
|  |  | ||||||
| 	nwrite = evbuffer_write(tty->out, tty->fd); | 	nwrite = evbuffer_write(tty->out, c->fd); | ||||||
| 	if (nwrite == -1) | 	if (nwrite == -1) | ||||||
| 		return; | 		return; | ||||||
| 	log_debug("%s: wrote %d bytes (of %zu)", c->name, nwrite, size); | 	log_debug("%s: wrote %d bytes (of %zu)", c->name, nwrite, size); | ||||||
| @@ -250,7 +250,7 @@ tty_open(struct tty *tty, char **cause) | |||||||
| 	struct client	*c = tty->client; | 	struct client	*c = tty->client; | ||||||
|  |  | ||||||
| 	tty->term = tty_term_create(tty, c->term_name, &c->term_features, | 	tty->term = tty_term_create(tty, c->term_name, &c->term_features, | ||||||
| 	    tty->fd, cause); | 	    c->fd, cause); | ||||||
| 	if (tty->term == NULL) { | 	if (tty->term == NULL) { | ||||||
| 		tty_close(tty); | 		tty_close(tty); | ||||||
| 		return (-1); | 		return (-1); | ||||||
| @@ -259,13 +259,13 @@ tty_open(struct tty *tty, char **cause) | |||||||
|  |  | ||||||
| 	tty->flags &= ~(TTY_NOCURSOR|TTY_FREEZE|TTY_BLOCK|TTY_TIMER); | 	tty->flags &= ~(TTY_NOCURSOR|TTY_FREEZE|TTY_BLOCK|TTY_TIMER); | ||||||
|  |  | ||||||
| 	event_set(&tty->event_in, tty->fd, EV_PERSIST|EV_READ, | 	event_set(&tty->event_in, c->fd, EV_PERSIST|EV_READ, | ||||||
| 	    tty_read_callback, tty); | 	    tty_read_callback, tty); | ||||||
| 	tty->in = evbuffer_new(); | 	tty->in = evbuffer_new(); | ||||||
| 	if (tty->in == NULL) | 	if (tty->in == NULL) | ||||||
| 		fatal("out of memory"); | 		fatal("out of memory"); | ||||||
|  |  | ||||||
| 	event_set(&tty->event_out, tty->fd, EV_WRITE, tty_write_callback, tty); | 	event_set(&tty->event_out, c->fd, EV_WRITE, tty_write_callback, tty); | ||||||
| 	tty->out = evbuffer_new(); | 	tty->out = evbuffer_new(); | ||||||
| 	if (tty->out == NULL) | 	if (tty->out == NULL) | ||||||
| 		fatal("out of memory"); | 		fatal("out of memory"); | ||||||
| @@ -298,21 +298,19 @@ tty_start_tty(struct tty *tty) | |||||||
| 	struct termios	 tio; | 	struct termios	 tio; | ||||||
| 	struct timeval	 tv = { .tv_sec = 1 }; | 	struct timeval	 tv = { .tv_sec = 1 }; | ||||||
|  |  | ||||||
| 	if (tty->fd != -1 && tcgetattr(tty->fd, &tty->tio) == 0) { | 	setblocking(c->fd, 0); | ||||||
| 		setblocking(tty->fd, 0); | 	event_add(&tty->event_in, NULL); | ||||||
| 		event_add(&tty->event_in, NULL); |  | ||||||
|  |  | ||||||
| 		memcpy(&tio, &tty->tio, sizeof tio); | 	memcpy(&tio, &tty->tio, sizeof tio); | ||||||
| 		tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR|IGNCR|IMAXBEL|ISTRIP); | 	tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR|IGNCR|IMAXBEL|ISTRIP); | ||||||
| 		tio.c_iflag |= IGNBRK; | 	tio.c_iflag |= IGNBRK; | ||||||
| 		tio.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONLRET); | 	tio.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONLRET); | ||||||
| 		tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHONL|ECHOCTL| | 	tio.c_lflag &= ~(IEXTEN|ICANON|ECHO|ECHOE|ECHONL|ECHOCTL|ECHOPRT| | ||||||
| 		    ECHOPRT|ECHOKE|ISIG); | 	    ECHOKE|ISIG); | ||||||
| 		tio.c_cc[VMIN] = 1; | 	tio.c_cc[VMIN] = 1; | ||||||
| 		tio.c_cc[VTIME] = 0; | 	tio.c_cc[VTIME] = 0; | ||||||
| 		if (tcsetattr(tty->fd, TCSANOW, &tio) == 0) | 	if (tcsetattr(c->fd, TCSANOW, &tio) == 0) | ||||||
| 			tcflush(tty->fd, TCIOFLUSH); | 		tcflush(c->fd, TCIOFLUSH); | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	tty_putcode(tty, TTYC_SMCUP); | 	tty_putcode(tty, TTYC_SMCUP); | ||||||
|  |  | ||||||
| @@ -363,7 +361,8 @@ tty_send_requests(struct tty *tty) | |||||||
| void | void | ||||||
| tty_stop_tty(struct tty *tty) | tty_stop_tty(struct tty *tty) | ||||||
| { | { | ||||||
| 	struct winsize	ws; | 	struct client	*c = tty->client; | ||||||
|  | 	struct winsize	 ws; | ||||||
|  |  | ||||||
| 	if (!(tty->flags & TTY_STARTED)) | 	if (!(tty->flags & TTY_STARTED)) | ||||||
| 		return; | 		return; | ||||||
| @@ -382,9 +381,9 @@ tty_stop_tty(struct tty *tty) | |||||||
| 	 * 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 | ||||||
| 	 * with a dead tty. | 	 * with a dead tty. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (ioctl(tty->fd, TIOCGWINSZ, &ws) == -1) | 	if (ioctl(c->fd, TIOCGWINSZ, &ws) == -1) | ||||||
| 		return; | 		return; | ||||||
| 	if (tcsetattr(tty->fd, TCSANOW, &tty->tio) == -1) | 	if (tcsetattr(c->fd, TCSANOW, &tty->tio) == -1) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
| 	tty_raw(tty, tty_term_string2(tty->term, TTYC_CSR, 0, ws.ws_row - 1)); | 	tty_raw(tty, tty_term_string2(tty->term, TTYC_CSR, 0, ws.ws_row - 1)); | ||||||
| @@ -419,7 +418,7 @@ tty_stop_tty(struct tty *tty) | |||||||
| 		tty_raw(tty, tty_term_string(tty->term, TTYC_DSMG)); | 		tty_raw(tty, tty_term_string(tty->term, TTYC_DSMG)); | ||||||
| 	tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP)); | 	tty_raw(tty, tty_term_string(tty->term, TTYC_RMCUP)); | ||||||
|  |  | ||||||
| 	setblocking(tty->fd, 1); | 	setblocking(c->fd, 1); | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| @@ -440,11 +439,6 @@ tty_close(struct tty *tty) | |||||||
|  |  | ||||||
| 		tty->flags &= ~TTY_OPENED; | 		tty->flags &= ~TTY_OPENED; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (tty->fd != -1) { |  | ||||||
| 		close(tty->fd); |  | ||||||
| 		tty->fd = -1; |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| @@ -475,12 +469,13 @@ tty_update_features(struct tty *tty) | |||||||
| void | void | ||||||
| tty_raw(struct tty *tty, const char *s) | tty_raw(struct tty *tty, const char *s) | ||||||
| { | { | ||||||
| 	ssize_t	n, slen; | 	struct client	*c = tty->client; | ||||||
| 	u_int	i; | 	ssize_t		 n, slen; | ||||||
|  | 	u_int		 i; | ||||||
|  |  | ||||||
| 	slen = strlen(s); | 	slen = strlen(s); | ||||||
| 	for (i = 0; i < 5; i++) { | 	for (i = 0; i < 5; i++) { | ||||||
| 		n = write(tty->fd, s, slen); | 		n = write(c->fd, s, slen); | ||||||
| 		if (n >= 0) { | 		if (n >= 0) { | ||||||
| 			s += n; | 			s += n; | ||||||
| 			slen -= n; | 			slen -= n; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Thomas Adam
					Thomas Adam