I know that I can handle SIGCHLD as I want whenever it is sent. If I am not wrong, SIGCHLD is sent to the parent process every time the child is stopped, not only through termination but also because of an interrupt (eg SIGSTOP) sent. I want SIGCHLD to be handled specifically only on termination, not on interruption.
The only thing I tried is to have the child to send SIGUSR1 to the parent at termination (its last command is kill(getppid(), SIGUSR1);
, so I handle this signal instead. Of course it works as I want, but I am wondering: can I track termination without sending any additional signal only by SIGCHLD?
SA_NOCLDSTOP will prevent the generation of a SIGCHLD on child stop, as pointed out in another answer, and likely meets your needs.
For completeness, you could also inspect the si_code
member of the siginfo_t struct passed to your three-argument signal handler or sigwaitinfo
:
#define _POSIX_C_SOURCE 202405L
#include <signal.h>
....
void my_chld_handler(int signo, siginfo_t *info, void *context) {
switch (info->si_code) {
case CLD_EXITED:
case CLD_KILLED:
case CLD_DUMPED:
break;
default: /* ignore TRAPPED STOPPED CONTINUED */
return;
}
... handle child termination ...
}
....
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = my_chld_handler;
sigaction(SIGCHLD, &sa, NULL);
....