diff --git a/CHANGELOG.md b/CHANGELOG.md index db325da7..44093dc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,8 @@ `tweak.allow-overflowing-double-width-glyphs`. * Regression: crash when a single-char, double-width glyph is in the last column, and `tweak.allow-overflowing-double-width-glyphs=yes`. +* FD exhaustion when repeatedly entering/exiting URL mode with many + URLs. ### Security diff --git a/url-mode.c b/url-mode.c index 5f56a2f6..8ac5631e 100644 --- a/url-mode.c +++ b/url-mode.c @@ -14,6 +14,7 @@ #include "grid.h" #include "render.h" #include "selection.h" +#include "shm.h" #include "spawn.h" #include "terminal.h" #include "uri.h" @@ -728,7 +729,9 @@ urls_reset(struct terminal *term) if (term->window != NULL) { tll_foreach(term->window->urls, it) { + const struct url *url = it->item.url; wayl_win_subsurface_destroy(&it->item.surf); + shm_purge(term->wl->shm, shm_cookie_url(url)); tll_remove(term->window->urls, it); } } diff --git a/wayland.c b/wayland.c index 80fef88a..ecc4f31e 100644 --- a/wayland.c +++ b/wayland.c @@ -26,6 +26,7 @@ #include "input.h" #include "render.h" #include "selection.h" +#include "shm.h" #include "util.h" #include "xmalloc.h" @@ -1410,6 +1411,9 @@ wayl_win_destroy(struct wl_window *win) if (win == NULL) return; + struct terminal *term = win->term; + struct wl_shm *shm = term->wl->shm; + if (win->csd.move_timeout_fd != -1) close(win->csd.move_timeout_fd); @@ -1457,6 +1461,7 @@ wayl_win_destroy(struct wl_window *win) tll_foreach(win->urls, it) { wayl_win_subsurface_destroy(&it->item.surf); + shm_purge(shm, shm_cookie_url(it->item.url)); tll_remove(win->urls, it); }