Search code examples
cprocesssignal-handling

Catching a signal only in a specific occasion in C


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?


Solution

  • 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);
    ....