summaryrefslogtreecommitdiffstats
path: root/server-client.c
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2020-06-01 12:01:20 +0100
committerThomas Adam <thomas@xteddy.org>2020-06-01 12:01:20 +0100
commit91e40de2da5124b1593c1c25462b8c9a36b8ebfd (patch)
treebaae9e8fbba21c26851ca4f451105ac194a1d688 /server-client.c
parent5ef790a6c41f5b78d2e757612b75cb9142b9173f (diff)
parenta54a88edd6fd893d4370feb9f9136e13096b891c (diff)
Merge branch 'obsd-master'
Diffstat (limited to 'server-client.c')
-rw-r--r--server-client.c82
1 files changed, 50 insertions, 32 deletions
diff --git a/server-client.c b/server-client.c
index ac2272fc..b3394e65 100644
--- a/server-client.c
+++ b/server-client.c
@@ -56,6 +56,9 @@ static void server_client_dispatch_read_data(struct client *,
static void server_client_dispatch_read_done(struct client *,
struct imsg *);
+/* Maximum data allowed to be held for a pane for a control client. */
+#define SERVER_CLIENT_PANE_LIMIT 16777216
+
/* Compare client windows. */
static int
server_client_window_cmp(struct client_window *cw1,
@@ -78,7 +81,7 @@ server_client_how_many(void)
n = 0;
TAILQ_FOREACH(c, &clients, entry) {
- if (c->session != NULL && (~c->flags & CLIENT_DETACHING))
+ if (c->session != NULL && (~c->flags & CLIENT_UNATTACHEDFLAGS))
n++;
}
return (n);
@@ -384,7 +387,7 @@ server_client_suspend(struct client *c)
{
struct session *s = c->session;
- if (s == NULL || (c->flags & CLIENT_DETACHING))
+ if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
return;
tty_stop_tty(&c->tty);
@@ -398,12 +401,14 @@ server_client_detach(struct client *c, enum msgtype msgtype)
{
struct session *s = c->session;
- if (s == NULL || (c->flags & CLIENT_DETACHING))
+ if (s == NULL || (c->flags & CLIENT_UNATTACHEDFLAGS))
return;
- c->flags |= CLIENT_DETACHING;
- notify_client("client-detached", c);
- proc_send(c->peer, msgtype, -1, s->name, strlen(s->name) + 1);
+ c->flags |= CLIENT_EXIT;
+
+ c->exit_type = CLIENT_EXIT_DETACH;
+ c->exit_msgtype = msgtype;
+ c->exit_session = xstrdup(s->name);
}
/* Execute command to replace a client. */
@@ -1505,12 +1510,12 @@ server_client_check_pane_buffer(struct window_pane *wp)
u_int attached_clients = 0;
/*
- * Work out the minimum acknowledged size. This is the most that can be
- * removed from the buffer.
+ * Work out the minimum used size. This is the most that can be removed
+ * from the buffer.
*/
- minimum = wp->offset.acknowledged;
- if (wp->pipe_fd != -1 && wp->pipe_offset.acknowledged < minimum)
- minimum = wp->pipe_offset.acknowledged;
+ minimum = wp->offset.used;
+ if (wp->pipe_fd != -1 && wp->pipe_offset.used < minimum)
+ minimum = wp->pipe_offset.used;
TAILQ_FOREACH(c, &clients, entry) {
if (c->session == NULL)
continue;
@@ -1528,11 +1533,13 @@ server_client_check_pane_buffer(struct window_pane *wp)
if (!flag)
off = 0;
- log_debug("%s: %s has %zu bytes used, %zu bytes acknowledged "
- "for %%%u", __func__, c->name, wpo->used, wpo->acknowledged,
- wp->id);
- if (wpo->acknowledged < minimum)
- minimum = wpo->acknowledged;
+ log_debug("%s: %s has %zu bytes used for %%%u", __func__,
+ c->name, wpo->used - wp->base_offset, wp->id);
+ if (wpo->used - wp->base_offset > SERVER_CLIENT_PANE_LIMIT) {
+ control_flush(c);
+ c->flags |= CLIENT_EXIT;
+ } else if (wpo->used < minimum)
+ minimum = wpo->used;
}
if (attached_clients == 0)
off = 0;
@@ -1541,8 +1548,8 @@ server_client_check_pane_buffer(struct window_pane *wp)
goto out;
/* Drain the buffer. */
- log_debug("%s: %%%u has %zu minimum (of %zu) bytes acknowledged",
- __func__, wp->id, minimum, EVBUFFER_LENGTH(evb));
+ log_debug("%s: %%%u has %zu minimum (of %zu) bytes used", __func__,
+ wp->id, minimum, EVBUFFER_LENGTH(evb));
evbuffer_drain(evb, minimum);
/*
@@ -1551,20 +1558,15 @@ server_client_check_pane_buffer(struct window_pane *wp)
*/
if (wp->base_offset > SIZE_MAX - minimum) {
log_debug("%s: %%%u base offset has wrapped", __func__, wp->id);
- wp->offset.acknowledged -= wp->base_offset;
wp->offset.used -= wp->base_offset;
- if (wp->pipe_fd != -1) {
- wp->pipe_offset.acknowledged -= wp->base_offset;
+ if (wp->pipe_fd != -1)
wp->pipe_offset.used -= wp->base_offset;
- }
TAILQ_FOREACH(c, &clients, entry) {
if (c->session == NULL || (~c->flags & CLIENT_CONTROL))
continue;
wpo = control_pane_offset(c, wp, &flag);
- if (wpo != NULL && !flag) {
- wpo->acknowledged -= wp->base_offset;
+ if (wpo != NULL && !flag)
wpo->used -= wp->base_offset;
- }
}
wp->base_offset = minimum;
} else
@@ -1577,6 +1579,7 @@ out:
* clients, all of which are control clients which are not able to
* accept any more data.
*/
+ log_debug("%s: pane %%%u is %s", __func__, wp->id, off ? "off" : "on");
if (off)
bufferevent_disable(wp->event, EV_READ);
else
@@ -1768,12 +1771,16 @@ static void
server_client_check_exit(struct client *c)
{
struct client_file *cf;
+ const char *name = c->exit_session;
- if (~c->flags & CLIENT_EXIT)
- return;
- if (c->flags & CLIENT_EXITED)
+ if ((c->flags & CLIENT_EXITED) || (~c->flags & CLIENT_EXIT))
return;
+ if (c->flags & CLIENT_CONTROL) {
+ control_flush(c);
+ if (!control_all_done(c))
+ return;
+ }
RB_FOREACH(cf, client_files, &c->files) {
if (EVBUFFER_LENGTH(cf->buffer) != 0)
return;
@@ -1781,8 +1788,20 @@ server_client_check_exit(struct client *c)
if (c->flags & CLIENT_ATTACHED)
notify_client("client-detached", c);
- proc_send(c->peer, MSG_EXIT, -1, &c->retval, sizeof c->retval);
c->flags |= CLIENT_EXITED;
+
+ switch (c->exit_type) {
+ case CLIENT_EXIT_RETURN:
+ proc_send(c->peer, MSG_EXIT, -1, &c->retval, sizeof c->retval);
+ break;
+ case CLIENT_EXIT_SHUTDOWN:
+ proc_send(c->peer, MSG_SHUTDOWN, -1, NULL, 0);
+ break;
+ case CLIENT_EXIT_DETACH:
+ proc_send(c->peer, c->exit_msgtype, -1, name, strlen(name) + 1);
+ break;
+ }
+ free(c->exit_session);
}
/* Redraw timer callback. */
@@ -1994,7 +2013,6 @@ server_client_dispatch(struct imsg *imsg, void *arg)
case MSG_EXITING:
if (datalen != 0)
fatalx("bad MSG_EXITING size");
-
c->session = NULL;
tty_close(&c->tty);
proc_send(c->peer, MSG_EXITED, -1, NULL, 0);
@@ -2048,7 +2066,7 @@ server_client_command_done(struct cmdq_item *item, __unused void *data)
if (~c->flags & CLIENT_ATTACHED)
c->flags |= CLIENT_EXIT;
- else if (~c->flags & CLIENT_DETACHING)
+ else if (~c->flags & CLIENT_EXIT)
tty_send_requests(&c->tty);
return (CMD_RETURN_NORMAL);
}
@@ -2374,7 +2392,7 @@ server_client_set_flags(struct client *c, const char *flags)
else
c->flags |= flag;
if (flag == CLIENT_CONTROL_NOOUTPUT)
- control_free_offsets(c);
+ control_reset_offsets(c);
}
free(copy);
}