alexstamy
alexstamy

Reputation: 45

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?

Upvotes: 2

Views: 79

Answers (2)

pilcrow
pilcrow

Reputation: 58681

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

Upvotes: 2

Nate Eldredge
Nate Eldredge

Reputation: 58653

It sounds like you want the SA_NOCLDSTOP flag for sigaction.

From POSIX:

SA_NOCLDSTOP Do not generate SIGCHLD when children stop [ or stopped children continue ].

If sig is SIGCHLD and the SA_NOCLDSTOP flag is not set in sa_flags, and the implementation supports the SIGCHLD signal, then a SIGCHLD signal shall be generated for the calling process whenever any of its child processes stop [ and a SIGCHLD signal may be generated for the calling process whenever any of its stopped child processes are continued ]. If sig is SIGCHLD and the SA_NOCLDSTOP flag is set in sa_flags, then the implementation shall not generate a SIGCHLD signal in this way.

Upvotes: 5

Related Questions