diff --git a/cmd-queue.c b/cmd-queue.c index a9ce469bc..e84c265f7 100644 --- a/cmd-queue.c +++ b/cmd-queue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-queue.c,v 1.123 2026/08/24 20:34:26 nicm Exp $ */ +/* $OpenBSD: cmd-queue.c,v 1.124 2026/09/22 06:46:50 nicm Exp $ */ /* * Copyright (c) 2013 Nicholas Marriott @@ -580,6 +580,9 @@ cmdq_fire_command(struct cmdq_item *item) int flags, quiet = 0; char *tmp; + if (item->client != NULL && (item->client->flags & CLIENT_DEAD)) + return (CMD_RETURN_ERROR); + if (cfg_finished) cmdq_add_message(item); if (log_get_level() > 1) { diff --git a/cmd-wait-for.c b/cmd-wait-for.c index 0e4130fcd..7326c7519 100644 --- a/cmd-wait-for.c +++ b/cmd-wait-for.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-wait-for.c,v 1.23 2026/07/10 13:38:45 nicm Exp $ */ +/* $OpenBSD: cmd-wait-for.c,v 1.24 2026/09/22 06:46:50 nicm Exp $ */ /* * Copyright (c) 2013 Nicholas Marriott @@ -480,6 +480,40 @@ cmd_wait_for_unlock(struct cmdq_item *item, const char *name, return (CMD_RETURN_NORMAL); } +void +cmd_wait_for_client_lost(struct client *c) +{ + struct wait_channel *wc, *wc1; + struct wait_item *wi, *wi1; + struct wait_event_item *wei, *wei1; + + TAILQ_FOREACH_SAFE(wei, &wait_event_items, entry, wei1) { + if (cmdq_get_client(wei->item) == c) { + TAILQ_REMOVE(&wait_event_items, wei, entry); + cmdq_continue(wei->item); + cmd_wait_for_event_free(wei); + } + } + + RB_FOREACH_SAFE(wc, wait_channels, &wait_channels, wc1) { + TAILQ_FOREACH_SAFE(wi, &wc->waiters, entry, wi1) { + if (cmdq_get_client(wi->item) == c) { + cmdq_continue(wi->item); + TAILQ_REMOVE(&wc->waiters, wi, entry); + free(wi); + } + } + TAILQ_FOREACH_SAFE(wi, &wc->lockers, entry, wi1) { + if (cmdq_get_client(wi->item) == c) { + cmdq_continue(wi->item); + TAILQ_REMOVE(&wc->lockers, wi, entry); + free(wi); + } + } + cmd_wait_for_remove_empty(wc); + } +} + void cmd_wait_for_flush(void) { diff --git a/server-client.c b/server-client.c index 6aa0b562b..369e6d223 100644 --- a/server-client.c +++ b/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.512 2026/09/10 11:02:18 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.514 2026/09/22 06:46:50 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -502,6 +502,9 @@ server_client_lost(struct client *c) TAILQ_REMOVE(&clients, c, entry); log_debug("lost client %p", c); + cmd_wait_for_client_lost(c); + cmdq_next(c); + if (c->flags & CLIENT_ATTACHED) { server_client_attached_lost(c); events_fire_client("client-detached", c); diff --git a/tmux.h b/tmux.h index e9dffc814..21262af2f 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1443 2026/09/21 10:33:16 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1445 2026/09/22 06:46:50 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -3227,6 +3227,7 @@ void cmdq_print_data(struct cmdq_item *, struct evbuffer *); void printflike(2, 3) cmdq_error(struct cmdq_item *, const char *, ...); /* cmd-wait-for.c */ +void cmd_wait_for_client_lost(struct client *); void cmd_wait_for_flush(void); /* client.c */