From: Alan T. DeKok Date: Mon, 13 Apr 2020 21:50:08 +0000 (-0400) Subject: kevent() will return an error if the process has already exited X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bbf9fa5fc3c750397ea4a2772c459814a0416bde;p=thirdparty%2Ffreeradius-server.git kevent() will return an error if the process has already exited so we just call waitpid() to reap its status --- diff --git a/src/lib/util/event.c b/src/lib/util/event.c index 027656ac1e7..2fb3e670d1b 100644 --- a/src/lib/util/event.c +++ b/src/lib/util/event.c @@ -1256,7 +1256,28 @@ int fr_event_pid_wait(TALLOC_CTX *ctx, fr_event_list_t *el, fr_event_pid_t const EV_SET(&evset, pid, EVFILT_PROC, EV_ADD | EV_ONESHOT, NOTE_EXIT, 0, ev); if (unlikely(kevent(el->kq, &evset, 1, NULL, 0, NULL) < 0)) { - fr_strerror_printf("Failed adding waiter for PID %ld", (long) pid); + pid_t child; + int status; + + talloc_free(ev); + + /* + * Print this error here, so that the caller gets + * the error from kevent(), and not waitpid(). + */ + fr_strerror_printf("Failed adding waiter for PID %ld - %s", (long) pid, fr_syserror(errno)); + + /* + * If the child exited before kevent() was + * called, we need to get its status via + * waitpid(). + */ + child = waitpid(pid, &status, WNOHANG); + if (child == pid) { + wait_fn(el, pid, status, uctx); + return 0; + } + return -1; } talloc_set_destructor(ev, _event_pid_free);