From e16792c757200d679edc3918eea12a18ec12b5a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alin=20N=C4=83stac?= Date: Fri, 3 Jan 2020 17:16:17 +0100 Subject: [PATCH 05/14] Improve waiting for children on exit Gentoo-bug: https://bugs.gentoo.org/122795 --- pppd/main.c | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/pppd/main.c b/pppd/main.c index 0e8bc87..6c0a173 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -245,6 +245,7 @@ static void holdoff_end(void *); static void forget_child(int pid, int status); static int reap_kids(void); static void childwait_end(void *); +static void wait_children(void); #ifdef USE_TDB static void update_db_entry(void); @@ -560,26 +561,12 @@ main(int argc, char *argv[]) if (!persist) break; } - } - /* Wait for scripts to finish */ - reap_kids(); - if (n_children > 0) { - if (child_wait > 0) - TIMEOUT(childwait_end, NULL, child_wait); - if (debug) { - struct subprocess *chp; - dbglog("Waiting for %d child processes...", n_children); - for (chp = children; chp != NULL; chp = chp->next) - dbglog(" script %s, pid %d", chp->prog, chp->pid); - } - while (n_children > 0 && !childwait_done) { - handle_events(); - if (kill_link && !childwait_done) - childwait_end(NULL); - } + wait_children(); } + wait_children(); + die(status); return 0; } @@ -1831,6 +1818,36 @@ record_child(int pid, char *prog, void (*done)(void *), void *arg, int killable) } } +/* + * wait_children - wait for scripts to finish. + * if child_wait is 0, wait indefinitely. + * else, kill'em all at the end of timeout + */ +static void +wait_children() +{ + /* Wait for scripts to finish */ + reap_kids(); + if (n_children > 0) { + childwait_done = 0; + if (child_wait > 0) + TIMEOUT(childwait_end, NULL, child_wait); + if (debug) { + struct subprocess *chp; + dbglog("Waiting for %d child processes...", n_children); + for (chp = children; chp != NULL; chp = chp->next) + dbglog(" script %s, pid %d", chp->prog, chp->pid); + } + while (n_children > 0 && !childwait_done) { + handle_events(); + if (asked_to_quit && !childwait_done) + childwait_end(NULL); + } + if (child_wait > 0) + UNTIMEOUT(childwait_end, NULL); + } +} + /* * childwait_end - we got fed up waiting for the child processes to * exit, send them all a SIGTERM. -- 2.30.0