Attempt to keep running if a child process dies.

If a child process dies unexpectedly, log the error and
try and tidy up so the main process continues to run and
doesn't block awaiting the dead child.
This commit is contained in:
Simon Kelley
2025-01-13 10:56:19 +00:00
parent 424aaa0f9d
commit b915c9a661

View File

@@ -1484,7 +1484,7 @@ static void async_event(int pipe, time_t now)
{ {
pid_t p; pid_t p;
struct event_desc ev; struct event_desc ev;
int i, check = 0; int wstatus, i, check = 0;
char *msg; char *msg;
/* NOTE: the memory used to return msg is leaked: use msgs in events only /* NOTE: the memory used to return msg is leaked: use msgs in events only
@@ -1547,7 +1547,7 @@ static void async_event(int pipe, time_t now)
case EVENT_CHILD: case EVENT_CHILD:
/* See Stevens 5.10 */ /* See Stevens 5.10 */
while ((p = waitpid(-1, NULL, WNOHANG)) != 0) while ((p = waitpid(-1, &wstatus, WNOHANG)) != 0)
if (p == -1) if (p == -1)
{ {
if (errno != EINTR) if (errno != EINTR)
@@ -1558,6 +1558,20 @@ static void async_event(int pipe, time_t now)
if (daemon->tcp_pids[i] == p) if (daemon->tcp_pids[i] == p)
{ {
daemon->tcp_pids[i] = 0; daemon->tcp_pids[i] = 0;
if (!WIFEXITED(wstatus))
{
/* If a helper process dies, (eg with SIGSEV)
log that and attempt to patch things up so that the
parent can continue to function. */
my_syslog(LOG_WARNING, _("TCP helper process %u died unexpectedly"), (unsigned int)p);
if (daemon->tcp_pipes[i] != -1)
{
close(daemon->tcp_pipes[i]);
daemon->tcp_pipes[i] = -1;
}
}
/* tcp_pipes == -1 && tcp_pids == 0 required to free slot */ /* tcp_pipes == -1 && tcp_pids == 0 required to free slot */
if (daemon->tcp_pipes[i] == -1) if (daemon->tcp_pipes[i] == -1)
daemon->metrics[METRIC_TCP_CONNECTIONS]--; daemon->metrics[METRIC_TCP_CONNECTIONS]--;
@@ -2092,7 +2106,7 @@ static void do_tcp_connection(struct listener *listener, time_t now, int slot)
Reset that here. */ Reset that here. */
if ((flags = fcntl(confd, F_GETFL, 0)) != -1) if ((flags = fcntl(confd, F_GETFL, 0)) != -1)
while(retry_send(fcntl(confd, F_SETFL, flags & ~O_NONBLOCK))); while(retry_send(fcntl(confd, F_SETFL, flags & ~O_NONBLOCK)));
buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns); buff = tcp_request(confd, now, &tcp_addr, netmask, auth_dns);
if (buff) if (buff)