mirror of
https://github.com/tmux/tmux.git
synced 2026-09-14 09:11:59 +00:00
Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master: Draw bottom border with pane status line at the top. Bound the memory used by buffered control mode command replies (to 64 MB), GitHub issue 5565 from kagari dot shusei at proton dot me. Do not adjust prompt position on invalid Unicode, from Kaixuan Li.
This commit is contained in:
55
control.c
55
control.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: control.c,v 1.67 2026/09/03 21:35:38 nicm Exp $ */
|
||||
/* $OpenBSD: control.c,v 1.68 2026/09/09 08:30:05 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -108,6 +108,7 @@ struct control_state {
|
||||
u_int pending_count;
|
||||
|
||||
TAILQ_HEAD(, control_block) all_blocks;
|
||||
size_t queued_reply_bytes;
|
||||
|
||||
struct bufferevent *read_event;
|
||||
struct bufferevent *write_event;
|
||||
@@ -132,6 +133,9 @@ struct control_state {
|
||||
/* Maximum age for clients that are not using pause mode. */
|
||||
#define CONTROL_MAXIMUM_AGE 300000
|
||||
|
||||
/* Maximum buffered command replies for a client that is not reading. */
|
||||
#define CONTROL_MAXIMUM_REPLY_BUFFER (64 * 1024 * 1024)
|
||||
|
||||
/* Flags to ignore client. */
|
||||
#define CONTROL_IGNORE_FLAGS \
|
||||
(CLIENT_CONTROL_NOOUTPUT| \
|
||||
@@ -165,6 +169,15 @@ RB_GENERATE_STATIC(control_windows, control_window, entry, control_window_cmp);
|
||||
static void
|
||||
control_free_block(struct control_state *cs, struct control_block *cb)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
if (cb->size == 0 && cb->line != NULL) {
|
||||
size = strlen(cb->line) + 1;
|
||||
if (cs->queued_reply_bytes > size)
|
||||
cs->queued_reply_bytes -= size;
|
||||
else
|
||||
cs->queued_reply_bytes = 0;
|
||||
}
|
||||
free(cb->line);
|
||||
TAILQ_REMOVE(&cs->all_blocks, cb, all_entry);
|
||||
free(cb);
|
||||
@@ -407,16 +420,52 @@ control_reset_pane(struct client *c, struct window_pane *wp)
|
||||
memcpy(&cp->queued, &wp->offset, sizeof cp->queued);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the replies buffered for a client, including one about to be
|
||||
* added, have grown too large and kill it if so. Returns 1 if further output
|
||||
* for the client should be dropped.
|
||||
*/
|
||||
static int
|
||||
control_check_reply_buffer(struct client *c, size_t added)
|
||||
{
|
||||
struct control_state *cs = c->control_state;
|
||||
size_t size;
|
||||
|
||||
if (c->flags & CLIENT_CONTROL_DISCARD)
|
||||
return (1);
|
||||
size = EVBUFFER_LENGTH(cs->write_event->output);
|
||||
size += cs->queued_reply_bytes;
|
||||
size += added;
|
||||
if (size < CONTROL_MAXIMUM_REPLY_BUFFER)
|
||||
return (0);
|
||||
|
||||
log_debug("%s: %s: %zu bytes of replies buffered", __func__, c->name,
|
||||
size);
|
||||
if (~c->flags & CLIENT_EXIT) {
|
||||
c->exit_message = xstrdup("too far behind");
|
||||
c->flags |= CLIENT_EXIT;
|
||||
control_discard(c);
|
||||
}
|
||||
c->flags |= CLIENT_CONTROL_DISCARD;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Write an already-formatted line, queueing it behind %output if needed. */
|
||||
static void
|
||||
control_write_line(struct client *c, char *line)
|
||||
{
|
||||
struct control_state *cs = c->control_state;
|
||||
struct control_block *cb;
|
||||
size_t size = strlen(line) + 1;
|
||||
|
||||
if (control_check_reply_buffer(c, size)) {
|
||||
free(line);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TAILQ_EMPTY(&cs->all_blocks)) {
|
||||
log_debug("%s: %s: writing line: %s", __func__, c->name, line);
|
||||
bufferevent_write(cs->write_event, line, strlen(line));
|
||||
bufferevent_write(cs->write_event, line, size - 1);
|
||||
bufferevent_write(cs->write_event, "\n", 1);
|
||||
bufferevent_enable(cs->write_event, EV_WRITE);
|
||||
free(line);
|
||||
@@ -426,6 +475,7 @@ control_write_line(struct client *c, char *line)
|
||||
cb = xcalloc(1, sizeof *cb);
|
||||
cb->line = line;
|
||||
TAILQ_INSERT_TAIL(&cs->all_blocks, cb, all_entry);
|
||||
cs->queued_reply_bytes += size;
|
||||
cb->t = get_timer();
|
||||
|
||||
log_debug("%s: %s: storing line: %s", __func__, c->name, cb->line);
|
||||
@@ -1007,6 +1057,7 @@ control_discard_all(struct client *c)
|
||||
control_discard(c);
|
||||
TAILQ_FOREACH_SAFE(cb, &cs->all_blocks, all_entry, cb1)
|
||||
control_free_block(cs, cb);
|
||||
cs->queued_reply_bytes = 0;
|
||||
bufferevent_disable(cs->write_event, EV_WRITE);
|
||||
}
|
||||
|
||||
|
||||
8
prompt.c
8
prompt.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: prompt.c,v 1.6 2026/08/17 06:45:16 nicm Exp $ */
|
||||
/* $OpenBSD: prompt.c,v 1.7 2026/09/09 07:53:03 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -1493,9 +1493,11 @@ append_key:
|
||||
utf8_set(&tmp, key);
|
||||
if (key <= 0x1f || key == 0x7f)
|
||||
tmp.width = 2;
|
||||
} else if (KEYC_IS_UNICODE(key))
|
||||
} else if (KEYC_IS_UNICODE(key)) {
|
||||
utf8_to_data(key, &tmp);
|
||||
else
|
||||
if (tmp.size == 0)
|
||||
return (PROMPT_KEY_HANDLED);
|
||||
} else
|
||||
return (PROMPT_KEY_HANDLED);
|
||||
|
||||
pr->buffer = xreallocarray(pr->buffer, size + 2,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: screen-redraw.c,v 1.158 2026/09/01 19:50:58 nicm Exp $ */
|
||||
/* $OpenBSD: screen-redraw.c,v 1.159 2026/09/09 08:31:42 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -713,7 +713,7 @@ redraw_mark_pane_borders(struct redraw_build_ctx *bctx, struct window_pane *wp,
|
||||
} else {
|
||||
mark_right = (right <= (int)bctx->w->sx);
|
||||
mark_bottom = (bottom <= (int)bctx->w->sy);
|
||||
if (pane_status == PANE_STATUS_TOP)
|
||||
if (pane_status == PANE_STATUS_TOP && bottom < (int)bctx->w->sy)
|
||||
mark_bottom = 0;
|
||||
else if (pane_status == PANE_STATUS_BOTTOM)
|
||||
mark_top = 0;
|
||||
|
||||
3
tmux.h
3
tmux.h
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tmux.h,v 1.1437 2026/09/09 07:03:39 nicm Exp $ */
|
||||
/* $OpenBSD: tmux.h,v 1.1438 2026/09/09 08:30:05 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -2302,6 +2302,7 @@ struct client {
|
||||
#define CLIENT_ASSUMEPASTING 0x2000000000ULL
|
||||
#define CLIENT_WRITE_ACK 0x4000000000ULL
|
||||
#define CLIENT_NO_DETACH_ON_DESTROY 0x8000000000ULL
|
||||
#define CLIENT_CONTROL_DISCARD 0x1000000000ULL
|
||||
#define CLIENT_ALLREDRAWFLAGS \
|
||||
(CLIENT_REDRAWWINDOW| \
|
||||
CLIENT_REDRAWSTATUS| \
|
||||
|
||||
Reference in New Issue
Block a user