diff --git a/pgo/pgo.c b/pgo/pgo.c index 120b8628..39c20de0 100644 --- a/pgo/pgo.c +++ b/pgo/pgo.c @@ -136,6 +136,7 @@ notify_notify(const struct terminal *term, const char *title, const char *body) } void reaper_add(struct reaper *reaper, pid_t pid, reaper_cb cb, void *cb_data) {} +void reaper_del(struct reaper *reaper, pid_t pid) {} int diff --git a/reaper.c b/reaper.c index 8ebd31a4..9d98854e 100644 --- a/reaper.c +++ b/reaper.c @@ -98,6 +98,17 @@ reaper_add(struct reaper *reaper, pid_t pid, reaper_cb cb, void *cb_data) ((struct child){.pid = pid, .cb = cb, .cb_data = cb_data})); } +void +reaper_del(struct reaper *reaper, pid_t pid) +{ + tll_foreach(reaper->children, it) { + if (it->item.pid == pid) { + tll_remove(reaper->children, it); + break; + } + } +} + static bool fdm_reap(struct fdm *fdm, int fd, int events, void *data) { @@ -127,23 +138,27 @@ fdm_reap(struct fdm *fdm, int fd, int events, void *data) } tll_foreach(reaper->children, it) { - struct child *child = &it->item; - pid_t pid = child->pid; + struct child *_child = &it->item; - if (pid != (pid_t)info.ssi_pid) + if (_child->pid != (pid_t)info.ssi_pid) continue; + /* Make sure we remove it *before* the callback, since it too + * may remove it */ + struct child child = it->item; + tll_remove(reaper->children, it); + bool reap_ourselves = true; - if (child->cb != NULL) - reap_ourselves = !child->cb(reaper, pid, child->cb_data); + if (child.cb != NULL) + reap_ourselves = !child.cb(reaper, child.pid, child.cb_data); if (reap_ourselves) { int result; - int res = waitpid(pid, &result, WNOHANG); + int res = waitpid(child.pid, &result, WNOHANG); if (res <= 0) { if (res < 0) - LOG_ERRNO("waitpid failed for pid=%d", pid); + LOG_ERRNO("waitpid failed for pid=%d", child.pid); continue; } @@ -154,8 +169,6 @@ fdm_reap(struct fdm *fdm, int fd, int events, void *data) else LOG_DBG("pid=%d: died of unknown resason", pid); } - - tll_remove(reaper->children, it); } if (hup) diff --git a/reaper.h b/reaper.h index f955aa44..2cd6dd6e 100644 --- a/reaper.h +++ b/reaper.h @@ -13,3 +13,4 @@ void reaper_destroy(struct reaper *reaper); typedef bool (*reaper_cb)(struct reaper *reaper, pid_t pid, void *data); void reaper_add(struct reaper *reaper, pid_t pid, reaper_cb cb, void *cb_data); +void reaper_del(struct reaper *reaper, pid_t pid); diff --git a/terminal.c b/terminal.c index 0ea04fc5..c05325ee 100644 --- a/terminal.c +++ b/terminal.c @@ -1334,6 +1334,9 @@ term_shutdown(struct terminal *term) fdm_del(term->fdm, term->blink.fd); fdm_del(term->fdm, term->flash.fd); + /* We’ll deal with this explicitly */ + reaper_del(term->reaper, term->slave); + if (term->window != NULL && term->window->is_configured) fdm_del(term->fdm, term->ptmx); else