mirror of
https://github.com/AuxXxilium/eudev.git
synced 2025-03-10 16:39:30 +07:00
manager: instead of using siginfo_t when reading SIGCHLD PIDs, run waitid() twice to avoid dropped signals
This commit is contained in:
parent
8d0e8067af
commit
4112df1635
44
manager.c
44
manager.c
@ -1440,26 +1440,53 @@ static int manager_dispatch_sigchld(Manager *m) {
|
||||
Unit *u;
|
||||
|
||||
zero(si);
|
||||
if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG) < 0) {
|
||||
|
||||
/* First we call waitd() for a PID and do not reap the
|
||||
* zombie. That way we can still access /proc/$PID for
|
||||
* it while it is a zombie. */
|
||||
if (waitid(P_ALL, 0, &si, WEXITED|WNOHANG|WNOWAIT) < 0) {
|
||||
|
||||
if (errno == ECHILD)
|
||||
break;
|
||||
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (si.si_pid == 0)
|
||||
if (si.si_pid <= 0)
|
||||
break;
|
||||
|
||||
if (si.si_code == CLD_EXITED && si.si_code == CLD_KILLED && si.si_code == CLD_DUMPED) {
|
||||
char *name = NULL;
|
||||
|
||||
get_process_name(si.si_pid, &name);
|
||||
log_debug("Got SIGCHLD for process %llu (%s)", (unsigned long long) si.si_pid, strna(name));
|
||||
free(name);
|
||||
}
|
||||
|
||||
/* And now, we actually reap the zombie. */
|
||||
if (waitid(P_PID, si.si_pid, &si, WEXITED) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (si.si_code != CLD_EXITED && si.si_code != CLD_KILLED && si.si_code != CLD_DUMPED)
|
||||
continue;
|
||||
|
||||
log_debug("child %llu died (code=%s, status=%i)", (long long unsigned) si.si_pid, sigchld_code_to_string(si.si_code), si.si_status);
|
||||
log_debug("Child %llu died (code=%s, status=%i/%s)",
|
||||
(long long unsigned) si.si_pid,
|
||||
sigchld_code_to_string(si.si_code),
|
||||
si.si_status,
|
||||
strna(si.si_code == CLD_EXITED ? exit_status_to_string(si.si_status) : strsignal(si.si_status)));
|
||||
|
||||
if (!(u = hashmap_remove(m->watch_pids, UINT32_TO_PTR(si.si_pid))))
|
||||
continue;
|
||||
|
||||
log_debug("child %llu belongs to %s", (long long unsigned) si.si_pid, unit_id(u));
|
||||
log_debug("Child %llu belongs to %s", (long long unsigned) si.si_pid, unit_id(u));
|
||||
|
||||
UNIT_VTABLE(u)->sigchld_event(u, si.si_pid, si.si_code, si.si_status);
|
||||
}
|
||||
@ -1495,16 +1522,9 @@ static int manager_process_signal_fd(Manager *m, bool *quit) {
|
||||
|
||||
switch (sfsi.ssi_signo) {
|
||||
|
||||
case SIGCHLD: {
|
||||
char *name = NULL;
|
||||
|
||||
get_process_name(sfsi.ssi_pid, &name);
|
||||
log_debug("Got SIGCHLD for process %llu (%s)", (unsigned long long) sfsi.ssi_pid, strna(name));
|
||||
free(name);
|
||||
|
||||
case SIGCHLD:
|
||||
sigchld = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
|
Loading…
Reference in New Issue
Block a user