mirror of
https://github.com/tmate-io/tmate-ssh-server.git
synced 2020-11-18 19:53:51 -08:00
Merge branch 'obsd-master'
This commit is contained in:
commit
00471dc783
@ -46,11 +46,11 @@ const struct cmd_entry cmd_server_info_entry = {
|
|||||||
cmd_show_messages_exec
|
cmd_show_messages_exec
|
||||||
};
|
};
|
||||||
|
|
||||||
void cmd_show_messages_server(struct cmd_q *);
|
int cmd_show_messages_server(struct cmd_q *);
|
||||||
void cmd_show_messages_terminals(struct cmd_q *);
|
int cmd_show_messages_terminals(struct cmd_q *, int);
|
||||||
void cmd_show_messages_jobs(struct cmd_q *);
|
int cmd_show_messages_jobs(struct cmd_q *, int);
|
||||||
|
|
||||||
void
|
int
|
||||||
cmd_show_messages_server(struct cmd_q *cmdq)
|
cmd_show_messages_server(struct cmd_q *cmdq)
|
||||||
{
|
{
|
||||||
char *tim;
|
char *tim;
|
||||||
@ -62,10 +62,12 @@ cmd_show_messages_server(struct cmd_q *cmdq)
|
|||||||
cmdq_print(cmdq, "socket path %s", socket_path);
|
cmdq_print(cmdq, "socket path %s", socket_path);
|
||||||
cmdq_print(cmdq, "debug level %d", debug_level);
|
cmdq_print(cmdq, "debug level %d", debug_level);
|
||||||
cmdq_print(cmdq, "protocol version %d", PROTOCOL_VERSION);
|
cmdq_print(cmdq, "protocol version %d", PROTOCOL_VERSION);
|
||||||
|
|
||||||
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
cmd_show_messages_terminals(struct cmd_q *cmdq)
|
cmd_show_messages_terminals(struct cmd_q *cmdq, int blank)
|
||||||
{
|
{
|
||||||
struct tty_term *term;
|
struct tty_term *term;
|
||||||
const struct tty_term_code_entry *ent;
|
const struct tty_term_code_entry *ent;
|
||||||
@ -75,8 +77,11 @@ cmd_show_messages_terminals(struct cmd_q *cmdq)
|
|||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
LIST_FOREACH(term, &tty_terms, entry) {
|
LIST_FOREACH(term, &tty_terms, entry) {
|
||||||
cmdq_print(cmdq,
|
if (blank) {
|
||||||
"Terminal %u: %s [references=%u, flags=0x%x]:",
|
cmdq_print(cmdq, "%s", "");
|
||||||
|
blank = 0;
|
||||||
|
}
|
||||||
|
cmdq_print(cmdq, "Terminal %u: %s [references=%u, flags=0x%x]:",
|
||||||
n, term->name, term->references, term->flags);
|
n, term->name, term->references, term->flags);
|
||||||
n++;
|
n++;
|
||||||
for (i = 0; i < NTTYCODE; i++) {
|
for (i = 0; i < NTTYCODE; i++) {
|
||||||
@ -105,21 +110,26 @@ cmd_show_messages_terminals(struct cmd_q *cmdq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return (n != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
cmd_show_messages_jobs(struct cmd_q *cmdq)
|
cmd_show_messages_jobs(struct cmd_q *cmdq, int blank)
|
||||||
{
|
{
|
||||||
struct job *job;
|
struct job *job;
|
||||||
u_int n;
|
u_int n;
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
LIST_FOREACH(job, &all_jobs, lentry) {
|
LIST_FOREACH(job, &all_jobs, lentry) {
|
||||||
cmdq_print(cmdq,
|
if (blank) {
|
||||||
"Job %u: %s [fd=%d, pid=%d, status=%d]",
|
cmdq_print(cmdq, "%s", "");
|
||||||
|
blank = 0;
|
||||||
|
}
|
||||||
|
cmdq_print(cmdq, "Job %u: %s [fd=%d, pid=%d, status=%d]",
|
||||||
n, job->cmd, job->fd, job->pid, job->status);
|
n, job->cmd, job->fd, job->pid, job->status);
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
return (n != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum cmd_retval
|
enum cmd_retval
|
||||||
@ -129,23 +139,19 @@ cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||||||
struct client *c;
|
struct client *c;
|
||||||
struct message_entry *msg;
|
struct message_entry *msg;
|
||||||
char *tim;
|
char *tim;
|
||||||
int done;
|
int done, blank;
|
||||||
|
|
||||||
done = 0;
|
done = blank = 0;
|
||||||
if (args_has(args, 'I') || self->entry == &cmd_server_info_entry) {
|
if (args_has(args, 'I') || self->entry == &cmd_server_info_entry) {
|
||||||
cmd_show_messages_server(cmdq);
|
blank = cmd_show_messages_server(cmdq);
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
if (args_has(args, 'T') || self->entry == &cmd_server_info_entry) {
|
if (args_has(args, 'T') || self->entry == &cmd_server_info_entry) {
|
||||||
if (done)
|
blank = cmd_show_messages_terminals(cmdq, blank);
|
||||||
cmdq_print(cmdq, "%s", "");
|
|
||||||
cmd_show_messages_terminals(cmdq);
|
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
if (args_has(args, 'J') || self->entry == &cmd_server_info_entry) {
|
if (args_has(args, 'J') || self->entry == &cmd_server_info_entry) {
|
||||||
if (done)
|
cmd_show_messages_jobs(cmdq, blank);
|
||||||
cmdq_print(cmdq, "%s", "");
|
|
||||||
cmd_show_messages_jobs(cmdq);
|
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
if (done)
|
if (done)
|
||||||
|
20
format.c
20
format.c
@ -495,6 +495,8 @@ format_defaults_session(struct format_tree *ft, struct session *s)
|
|||||||
{
|
{
|
||||||
struct session_group *sg;
|
struct session_group *sg;
|
||||||
time_t t;
|
time_t t;
|
||||||
|
struct winlink *wl;
|
||||||
|
char alerts[256], tmp[16];
|
||||||
|
|
||||||
ft->s = s;
|
ft->s = s;
|
||||||
|
|
||||||
@ -519,6 +521,24 @@ format_defaults_session(struct format_tree *ft, struct session *s)
|
|||||||
|
|
||||||
format_add(ft, "session_attached", "%u", s->attached);
|
format_add(ft, "session_attached", "%u", s->attached);
|
||||||
format_add(ft, "session_many_attached", "%d", s->attached > 1);
|
format_add(ft, "session_many_attached", "%d", s->attached > 1);
|
||||||
|
|
||||||
|
*alerts = '\0';
|
||||||
|
RB_FOREACH (wl, winlinks, &s->windows) {
|
||||||
|
if ((wl->flags & WINLINK_ALERTFLAGS) == 0)
|
||||||
|
continue;
|
||||||
|
snprintf(tmp, sizeof tmp, "%u", wl->idx);
|
||||||
|
|
||||||
|
if (*alerts != '\0')
|
||||||
|
strlcat(alerts, ",", sizeof alerts);
|
||||||
|
strlcat(alerts, tmp, sizeof alerts);
|
||||||
|
if (wl->flags & WINLINK_ACTIVITY)
|
||||||
|
strlcat(alerts, "#", sizeof alerts);
|
||||||
|
if (wl->flags & WINLINK_BELL)
|
||||||
|
strlcat(alerts, "!", sizeof alerts);
|
||||||
|
if (wl->flags & WINLINK_SILENCE)
|
||||||
|
strlcat(alerts, "~", sizeof alerts);
|
||||||
|
}
|
||||||
|
format_add(ft, "session_alerts", "%s", alerts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set default format keys for a client. */
|
/* Set default format keys for a client. */
|
||||||
|
16
input.c
16
input.c
@ -1069,7 +1069,6 @@ input_c0_dispatch(struct input_ctx *ictx)
|
|||||||
struct screen_write_ctx *sctx = &ictx->ctx;
|
struct screen_write_ctx *sctx = &ictx->ctx;
|
||||||
struct window_pane *wp = ictx->wp;
|
struct window_pane *wp = ictx->wp;
|
||||||
struct screen *s = sctx->s;
|
struct screen *s = sctx->s;
|
||||||
u_int trigger;
|
|
||||||
|
|
||||||
log_debug("%s: '%c", __func__, ictx->ch);
|
log_debug("%s: '%c", __func__, ictx->ch);
|
||||||
|
|
||||||
@ -1081,7 +1080,7 @@ input_c0_dispatch(struct input_ctx *ictx)
|
|||||||
break;
|
break;
|
||||||
case '\010': /* BS */
|
case '\010': /* BS */
|
||||||
screen_write_backspace(sctx);
|
screen_write_backspace(sctx);
|
||||||
goto count_c0;
|
break;
|
||||||
case '\011': /* HT */
|
case '\011': /* HT */
|
||||||
/* Don't tab beyond the end of the line. */
|
/* Don't tab beyond the end of the line. */
|
||||||
if (s->cx >= screen_size_x(s) - 1)
|
if (s->cx >= screen_size_x(s) - 1)
|
||||||
@ -1098,10 +1097,10 @@ input_c0_dispatch(struct input_ctx *ictx)
|
|||||||
case '\013': /* VT */
|
case '\013': /* VT */
|
||||||
case '\014': /* FF */
|
case '\014': /* FF */
|
||||||
screen_write_linefeed(sctx, 0);
|
screen_write_linefeed(sctx, 0);
|
||||||
goto count_c0;
|
break;
|
||||||
case '\015': /* CR */
|
case '\015': /* CR */
|
||||||
screen_write_carriagereturn(sctx);
|
screen_write_carriagereturn(sctx);
|
||||||
goto count_c0;
|
break;
|
||||||
case '\016': /* SO */
|
case '\016': /* SO */
|
||||||
ictx->cell.set = 1;
|
ictx->cell.set = 1;
|
||||||
break;
|
break;
|
||||||
@ -1113,15 +1112,6 @@ input_c0_dispatch(struct input_ctx *ictx)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
count_c0:
|
|
||||||
trigger = options_get_number(&wp->window->options, "c0-change-trigger");
|
|
||||||
if (trigger != 0 && ++wp->changes >= trigger) {
|
|
||||||
wp->flags |= PANE_DROP;
|
|
||||||
window_pane_timer_start(wp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ const char *options_table_status_position_list[] = {
|
|||||||
"top", "bottom", NULL
|
"top", "bottom", NULL
|
||||||
};
|
};
|
||||||
const char *options_table_bell_action_list[] = {
|
const char *options_table_bell_action_list[] = {
|
||||||
"none", "any", "current", NULL
|
"none", "any", "current", "other", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Server options. */
|
/* Server options. */
|
||||||
@ -295,7 +295,7 @@ const struct options_table_entry session_options_table[] = {
|
|||||||
|
|
||||||
{ .name = "set-titles-string",
|
{ .name = "set-titles-string",
|
||||||
.type = OPTIONS_TABLE_STRING,
|
.type = OPTIONS_TABLE_STRING,
|
||||||
.default_str = "#S:#I:#W - \"#T\""
|
.default_str = "#S:#I:#W - \"#T\" #{session_alerts}"
|
||||||
},
|
},
|
||||||
|
|
||||||
{ .name = "status",
|
{ .name = "status",
|
||||||
@ -484,20 +484,6 @@ const struct options_table_entry window_options_table[] = {
|
|||||||
"#{?pane_dead,[dead],}"
|
"#{?pane_dead,[dead],}"
|
||||||
},
|
},
|
||||||
|
|
||||||
{ .name = "c0-change-trigger",
|
|
||||||
.type = OPTIONS_TABLE_NUMBER,
|
|
||||||
.default_num = 250,
|
|
||||||
.minimum = 0,
|
|
||||||
.maximum = USHRT_MAX
|
|
||||||
},
|
|
||||||
|
|
||||||
{ .name = "c0-change-interval",
|
|
||||||
.type = OPTIONS_TABLE_NUMBER,
|
|
||||||
.default_num = 100,
|
|
||||||
.minimum = 1,
|
|
||||||
.maximum = USHRT_MAX
|
|
||||||
},
|
|
||||||
|
|
||||||
{ .name = "clock-mode-colour",
|
{ .name = "clock-mode-colour",
|
||||||
.type = OPTIONS_TABLE_COLOUR,
|
.type = OPTIONS_TABLE_COLOUR,
|
||||||
.default_num = 4
|
.default_num = 4
|
||||||
|
@ -77,13 +77,18 @@ server_window_check_bell(struct session *s, struct winlink *wl)
|
|||||||
if (c->session != s || c->flags & CLIENT_CONTROL)
|
if (c->session != s || c->flags & CLIENT_CONTROL)
|
||||||
continue;
|
continue;
|
||||||
if (!visual) {
|
if (!visual) {
|
||||||
if (c->session->curw->window == w || action == BELL_ANY)
|
if ((action == BELL_CURRENT &&
|
||||||
|
c->session->curw->window == w) ||
|
||||||
|
(action == BELL_OTHER &&
|
||||||
|
c->session->curw->window != w) ||
|
||||||
|
action == BELL_ANY)
|
||||||
tty_bell(&c->tty);
|
tty_bell(&c->tty);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c->session->curw->window == w)
|
if (action == BELL_CURRENT && c->session->curw->window == w)
|
||||||
status_message_set(c, "Bell in current window");
|
status_message_set(c, "Bell in current window");
|
||||||
else if (action == BELL_ANY)
|
else if (action == BELL_ANY || (action == BELL_OTHER &&
|
||||||
|
c->session->curw->window != w))
|
||||||
status_message_set(c, "Bell in window %d", wl->idx);
|
status_message_set(c, "Bell in window %d", wl->idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
27
tmux.1
27
tmux.1
@ -2379,16 +2379,18 @@ Set the base index from which an unused index should be searched when a new
|
|||||||
window is created.
|
window is created.
|
||||||
The default is zero.
|
The default is zero.
|
||||||
.It Xo Ic bell-action
|
.It Xo Ic bell-action
|
||||||
.Op Ic any | none | current
|
.Op Ic any | none | current | other
|
||||||
.Xc
|
.Xc
|
||||||
Set action on window bell.
|
Set action on window bell.
|
||||||
.Ic any
|
.Ic any
|
||||||
means a bell in any window linked to a session causes a bell in the current
|
means a bell in any window linked to a session causes a bell in the current
|
||||||
window of that session,
|
window of that session,
|
||||||
.Ic none
|
.Ic none
|
||||||
means all bells are ignored and
|
means all bells are ignored,
|
||||||
.Ic current
|
.Ic current
|
||||||
means only bells in windows other than the current window are ignored.
|
means only bells in windows other than the current window are ignored and
|
||||||
|
.Ic other
|
||||||
|
means bells in the current window are ignored but not those in other windows.
|
||||||
.It Xo Ic bell-on-alert
|
.It Xo Ic bell-on-alert
|
||||||
.Op Ic on | off
|
.Op Ic on | off
|
||||||
.Xc
|
.Xc
|
||||||
@ -2890,24 +2892,6 @@ used when the
|
|||||||
.Ic automatic-rename
|
.Ic automatic-rename
|
||||||
option is enabled.
|
option is enabled.
|
||||||
.Pp
|
.Pp
|
||||||
.It Ic c0-change-interval Ar interval
|
|
||||||
.It Ic c0-change-trigger Ar trigger
|
|
||||||
These two options configure a simple form of rate limiting for a pane.
|
|
||||||
If
|
|
||||||
.Nm
|
|
||||||
sees more than
|
|
||||||
.Ar trigger
|
|
||||||
C0 sequences that modify the screen (for example, carriage returns, linefeeds
|
|
||||||
or backspaces) in one millisecond, it will stop updating the pane immediately and
|
|
||||||
instead redraw it entirely every
|
|
||||||
.Ar interval
|
|
||||||
milliseconds.
|
|
||||||
This helps to prevent fast output (such as
|
|
||||||
.Xr yes 1 )
|
|
||||||
overwhelming the terminal.
|
|
||||||
The default is a trigger of 250 and an interval of 100.
|
|
||||||
A trigger of zero disables the rate limiting.
|
|
||||||
.Pp
|
|
||||||
.It Ic clock-mode-colour Ar colour
|
.It Ic clock-mode-colour Ar colour
|
||||||
Set clock colour.
|
Set clock colour.
|
||||||
.Pp
|
.Pp
|
||||||
@ -3325,6 +3309,7 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "pane_width" Ta "" Ta "Width of pane"
|
.It Li "pane_width" Ta "" Ta "Width of pane"
|
||||||
.It Li "scroll_region_lower" Ta "" Ta "Bottom of scroll region in pane"
|
.It Li "scroll_region_lower" Ta "" Ta "Bottom of scroll region in pane"
|
||||||
.It Li "scroll_region_upper" Ta "" Ta "Top of scroll region in pane"
|
.It Li "scroll_region_upper" Ta "" Ta "Top of scroll region in pane"
|
||||||
|
.It Li "session_alerts" Ta "" Ta "List of window indexes with alerts"
|
||||||
.It Li "session_attached" Ta "" Ta "Number of clients session is attached to"
|
.It Li "session_attached" Ta "" Ta "Number of clients session is attached to"
|
||||||
.It Li "session_activity" Ta "" Ta "Integer time of session last activity"
|
.It Li "session_activity" Ta "" Ta "Integer time of session last activity"
|
||||||
.It Li "session_activity_string" Ta "" Ta "String time of session last activity"
|
.It Li "session_activity_string" Ta "" Ta "String time of session last activity"
|
||||||
|
22
tmux.h
22
tmux.h
@ -60,6 +60,16 @@ extern char **environ;
|
|||||||
*/
|
*/
|
||||||
#define UTF8_SIZE 9
|
#define UTF8_SIZE 9
|
||||||
|
|
||||||
|
/*
|
||||||
|
* READ_SIZE is the maximum size of data to hold from a pty (the event high
|
||||||
|
* watermark). READ_BACKOFF is the amount of data waiting to be output to a tty
|
||||||
|
* before pty reads will be backed off. READ_TIME is how long to back off
|
||||||
|
* before the next read (in microseconds) if a tty is above READ_BACKOFF.
|
||||||
|
*/
|
||||||
|
#define READ_SIZE 1024
|
||||||
|
#define READ_BACKOFF 512
|
||||||
|
#define READ_TIME 100
|
||||||
|
|
||||||
/* Fatal errors. */
|
/* Fatal errors. */
|
||||||
#define fatal(msg) log_fatal("%s: %s", __func__, msg);
|
#define fatal(msg) log_fatal("%s: %s", __func__, msg);
|
||||||
#define fatalx(msg) log_fatalx("%s: %s", __func__, msg);
|
#define fatalx(msg) log_fatalx("%s: %s", __func__, msg);
|
||||||
@ -79,6 +89,7 @@ extern char **environ;
|
|||||||
#define BELL_NONE 0
|
#define BELL_NONE 0
|
||||||
#define BELL_ANY 1
|
#define BELL_ANY 1
|
||||||
#define BELL_CURRENT 2
|
#define BELL_CURRENT 2
|
||||||
|
#define BELL_OTHER 3
|
||||||
|
|
||||||
/* Special key codes. */
|
/* Special key codes. */
|
||||||
#define KEYC_NONE 0xfff
|
#define KEYC_NONE 0xfff
|
||||||
@ -848,12 +859,9 @@ struct window_pane {
|
|||||||
char tty[TTY_NAME_MAX];
|
char tty[TTY_NAME_MAX];
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
u_int changes;
|
|
||||||
struct event changes_timer;
|
|
||||||
u_int changes_redraw;
|
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
struct bufferevent *event;
|
struct bufferevent *event;
|
||||||
|
struct event timer;
|
||||||
|
|
||||||
struct input_ctx *ictx;
|
struct input_ctx *ictx;
|
||||||
|
|
||||||
@ -1602,8 +1610,9 @@ void tty_draw_line(struct tty *, const struct window_pane *, struct screen *,
|
|||||||
int tty_open(struct tty *, char **);
|
int tty_open(struct tty *, char **);
|
||||||
void tty_close(struct tty *);
|
void tty_close(struct tty *);
|
||||||
void tty_free(struct tty *);
|
void tty_free(struct tty *);
|
||||||
void tty_write(
|
void tty_write(void (*)(struct tty *, const struct tty_ctx *),
|
||||||
void (*)(struct tty *, const struct tty_ctx *), struct tty_ctx *);
|
struct tty_ctx *);
|
||||||
|
int tty_client_ready(struct client *, struct window_pane *wp);
|
||||||
void tty_cmd_alignmenttest(struct tty *, const struct tty_ctx *);
|
void tty_cmd_alignmenttest(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_cell(struct tty *, const struct tty_ctx *);
|
void tty_cmd_cell(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_clearendofline(struct tty *, const struct tty_ctx *);
|
void tty_cmd_clearendofline(struct tty *, const struct tty_ctx *);
|
||||||
@ -2111,7 +2120,6 @@ struct window_pane *window_pane_find_by_id_str(const char *);
|
|||||||
struct window_pane *window_pane_find_by_id(u_int);
|
struct window_pane *window_pane_find_by_id(u_int);
|
||||||
struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
|
struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
|
||||||
void window_pane_destroy(struct window_pane *);
|
void window_pane_destroy(struct window_pane *);
|
||||||
void window_pane_timer_start(struct window_pane *);
|
|
||||||
int window_pane_spawn(struct window_pane *, int, char **,
|
int window_pane_spawn(struct window_pane *, int, char **,
|
||||||
const char *, const char *, int, struct environ *,
|
const char *, const char *, int, struct environ *,
|
||||||
struct termios *, char **);
|
struct termios *, char **);
|
||||||
|
26
tty.c
26
tty.c
@ -723,9 +723,23 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp,
|
|||||||
tty_update_mode(tty, tty->mode, s);
|
tty_update_mode(tty, tty->mode, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
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)
|
||||||
|
return (0);
|
||||||
|
if (c->tty.flags & TTY_FREEZE)
|
||||||
|
return (0);
|
||||||
|
if (c->session->curw->window != wp->window)
|
||||||
|
return (0);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_write(
|
tty_write(void (*cmdfn)(struct tty *, const struct tty_ctx *),
|
||||||
void (*cmdfn)(struct tty *, const struct tty_ctx *), struct tty_ctx *ctx)
|
struct tty_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct window_pane *wp = ctx->wp;
|
struct window_pane *wp = ctx->wp;
|
||||||
struct client *c;
|
struct client *c;
|
||||||
@ -740,13 +754,7 @@ tty_write(
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
TAILQ_FOREACH(c, &clients, entry) {
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
if (c->session == NULL || c->tty.term == NULL)
|
if (!tty_client_ready(c, wp))
|
||||||
continue;
|
|
||||||
if (c->flags & CLIENT_SUSPENDED)
|
|
||||||
continue;
|
|
||||||
if (c->tty.flags & TTY_FREEZE)
|
|
||||||
continue;
|
|
||||||
if (c->session->curw->window != wp->window)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ctx->xoff = wp->xoff;
|
ctx->xoff = wp->xoff;
|
||||||
|
78
window.c
78
window.c
@ -740,8 +740,8 @@ window_pane_destroy(struct window_pane *wp)
|
|||||||
{
|
{
|
||||||
window_pane_reset_mode(wp);
|
window_pane_reset_mode(wp);
|
||||||
|
|
||||||
if (event_initialized(&wp->changes_timer))
|
if (event_initialized(&wp->timer))
|
||||||
evtimer_del(&wp->changes_timer);
|
evtimer_del(&wp->timer);
|
||||||
|
|
||||||
if (wp->fd != -1) {
|
if (wp->fd != -1) {
|
||||||
#ifdef HAVE_UTEMPTER
|
#ifdef HAVE_UTEMPTER
|
||||||
@ -885,64 +885,53 @@ window_pane_spawn(struct window_pane *wp, int argc, char **argv,
|
|||||||
|
|
||||||
wp->event = bufferevent_new(wp->fd, window_pane_read_callback, NULL,
|
wp->event = bufferevent_new(wp->fd, window_pane_read_callback, NULL,
|
||||||
window_pane_error_callback, wp);
|
window_pane_error_callback, wp);
|
||||||
|
|
||||||
|
bufferevent_setwatermark(wp->event, EV_READ, 0, READ_SIZE);
|
||||||
bufferevent_enable(wp->event, EV_READ|EV_WRITE);
|
bufferevent_enable(wp->event, EV_READ|EV_WRITE);
|
||||||
|
|
||||||
free(cmd);
|
free(cmd);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
window_pane_timer_start(struct window_pane *wp)
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
tv.tv_sec = 0;
|
|
||||||
tv.tv_usec = 1000;
|
|
||||||
|
|
||||||
evtimer_del(&wp->changes_timer);
|
|
||||||
evtimer_set(&wp->changes_timer, window_pane_timer_callback, wp);
|
|
||||||
evtimer_add(&wp->changes_timer, &tv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
window_pane_timer_callback(unused int fd, unused short events, void *data)
|
window_pane_timer_callback(unused int fd, unused short events, void *data)
|
||||||
{
|
{
|
||||||
struct window_pane *wp = data;
|
window_pane_read_callback(NULL, data);
|
||||||
struct window *w = wp->window;
|
|
||||||
u_int interval, trigger;
|
|
||||||
|
|
||||||
interval = options_get_number(&w->options, "c0-change-interval");
|
|
||||||
trigger = options_get_number(&w->options, "c0-change-trigger");
|
|
||||||
|
|
||||||
if (wp->changes_redraw++ == interval) {
|
|
||||||
wp->flags |= PANE_REDRAW;
|
|
||||||
wp->changes_redraw = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trigger == 0 || wp->changes < trigger) {
|
|
||||||
wp->flags |= PANE_REDRAW;
|
|
||||||
wp->flags &= ~PANE_DROP;
|
|
||||||
} else
|
|
||||||
window_pane_timer_start(wp);
|
|
||||||
wp->changes = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_pane_read_callback(unused struct bufferevent *bufev, void *data)
|
window_pane_read_callback(unused struct bufferevent *bufev, void *data)
|
||||||
{
|
{
|
||||||
struct window_pane *wp = data;
|
struct window_pane *wp = data;
|
||||||
|
struct evbuffer *evb = wp->event->input;
|
||||||
char *new_data;
|
char *new_data;
|
||||||
size_t new_size;
|
size_t new_size, available;
|
||||||
|
struct client *c;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
new_size = EVBUFFER_LENGTH(wp->event->input) - wp->pipe_off;
|
if (event_initialized(&wp->timer))
|
||||||
|
evtimer_del(&wp->timer);
|
||||||
|
|
||||||
|
log_debug("%%%u has %zu bytes", wp->id, EVBUFFER_LENGTH(evb));
|
||||||
|
|
||||||
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
|
if (!tty_client_ready(c, wp))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
available = EVBUFFER_LENGTH(c->tty.event->output);
|
||||||
|
if (available > READ_BACKOFF)
|
||||||
|
goto start_timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_size = EVBUFFER_LENGTH(evb) - wp->pipe_off;
|
||||||
if (wp->pipe_fd != -1 && new_size > 0) {
|
if (wp->pipe_fd != -1 && new_size > 0) {
|
||||||
new_data = EVBUFFER_DATA(wp->event->input);
|
new_data = EVBUFFER_DATA(evb);
|
||||||
bufferevent_write(wp->pipe_event, new_data, new_size);
|
bufferevent_write(wp->pipe_event, new_data, new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
input_parse(wp);
|
input_parse(wp);
|
||||||
|
|
||||||
wp->pipe_off = EVBUFFER_LENGTH(wp->event->input);
|
wp->pipe_off = EVBUFFER_LENGTH(evb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we get here, we're not outputting anymore, so set the silence
|
* If we get here, we're not outputting anymore, so set the silence
|
||||||
@ -951,11 +940,22 @@ window_pane_read_callback(unused struct bufferevent *bufev, void *data)
|
|||||||
wp->window->flags |= WINDOW_SILENCE;
|
wp->window->flags |= WINDOW_SILENCE;
|
||||||
if (gettimeofday(&wp->window->silence_timer, NULL) != 0)
|
if (gettimeofday(&wp->window->silence_timer, NULL) != 0)
|
||||||
fatal("gettimeofday failed.");
|
fatal("gettimeofday failed.");
|
||||||
|
return;
|
||||||
|
|
||||||
|
start_timer:
|
||||||
|
log_debug("%%%u backing off (%s %zu > %d)", wp->id, c->ttyname,
|
||||||
|
available, READ_BACKOFF);
|
||||||
|
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = READ_TIME;
|
||||||
|
|
||||||
|
evtimer_set(&wp->timer, window_pane_timer_callback, wp);
|
||||||
|
evtimer_add(&wp->timer, &tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
window_pane_error_callback(
|
window_pane_error_callback(unused struct bufferevent *bufev, unused short what,
|
||||||
unused struct bufferevent *bufev, unused short what, void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct window_pane *wp = data;
|
struct window_pane *wp = data;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user