From 21b3da3babae3c9a39c5181a16ea5c662cb44e07 Mon Sep 17 00:00:00 2001 From: nicm Date: Mon, 21 Sep 2026 12:43:36 +0000 Subject: [PATCH] Do not do anything in session_detach and rely on the caller destroying the session, otherwise grouped sessions can reuse a session with no windows. From Jeong, Heon in GitHub issue 5620. --- server-fn.c | 6 +++--- session.c | 13 +++++++++---- spawn.c | 6 +++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/server-fn.c b/server-fn.c index 754e0a514..21b8829eb 100644 --- a/server-fn.c +++ b/server-fn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-fn.c,v 1.153 2026/09/10 11:02:18 nicm Exp $ */ +/* $OpenBSD: server-fn.c,v 1.154 2026/09/21 12:43:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -311,8 +311,8 @@ server_link_window(struct session *src, struct winlink *srcwl, } if (killflag) { /* - * Can't use session_detach as it will destroy session - * if this makes it empty. + * Can't use session_detach as it won't detach the only + * window. */ events_fire_winlink("window-unlinked", dstwl); dstwl->flags &= ~WINLINK_ALERTFLAGS; diff --git a/session.c b/session.c index c0ea1306a..060e01fac 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.107 2026/08/05 07:35:35 nicm Exp $ */ +/* $OpenBSD: session.c,v 1.108 2026/09/21 12:43:36 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -338,10 +338,17 @@ session_attach(struct session *s, struct window *w, int idx, char **cause) return (wl); } -/* Detach a window from a session. */ +/* + * Detach a window from a session. Returns 1 if the window has not been + * detached - the caller must destroy the session. + */ int session_detach(struct session *s, struct winlink *wl) { + if (RB_MIN(winlinks, &s->windows) == wl && + RB_MAX(winlinks, &s->windows) == wl) + return (1); + if (s->curw == wl && session_last(s) != 0 && session_previous(s, 0) != 0) @@ -354,8 +361,6 @@ session_detach(struct session *s, struct winlink *wl) session_group_synchronize_from(s); - if (RB_EMPTY(&s->windows)) - return (1); return (0); } diff --git a/spawn.c b/spawn.c index 290b5da6f..22dbe041d 100644 --- a/spawn.c +++ b/spawn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: spawn.c,v 1.52 2026/08/20 09:19:24 nicm Exp $ */ +/* $OpenBSD: spawn.c,v 1.53 2026/09/21 12:43:36 nicm Exp $ */ /* * Copyright (c) 2019 Nicholas Marriott @@ -168,8 +168,8 @@ spawn_window(struct spawn_context *sc, char **cause) } if (wl != NULL) { /* - * Can't use session_detach as it will destroy session - * if this makes it empty. + * Can't use session_detach as it won't detach the only + * window. */ wl->flags &= ~WINLINK_ALERTFLAGS; events_fire_winlink("window-unlinked", wl);