Search code examples
csignalssigactionsigchld

Can i get the signal int constant (like SIGINT or SIGKILL) that terminated a process using using sigaction's flag siginfo with SIGCHLD in C?


I'm trying to figure out if i can get the signal that terminated a child process using a custom SIGCHLD handler passed to a sigaction with flag set to SA_SIGINFO. From what i understood the si_status should report an exit value or a signal value depending on si_code value.

This is the code for the SIGCHLD handler:

static void sigchdl (int sig, siginfo_t *siginfo, void *context)
{

  int code = siginfo -> si_code, status = siginfo -> si_status;

      if(code == CLD_EXITED) 
      if(WIFEXITED(status)) printf("the background command with PID: %ld                               has been successfull\n,(long)siginfo>si_pid);

      else if(code == CLD_KILLED) {

       //2 = SIGINT, 9 = SIGKILL, 15 = SIGTERM (man signal)

      if(WTERMSIG(status) == 2 || WTERMSIG(status) == 9 || WTERMSIG(status) == 15)

      printf("Il comando in background con PID: %ld e' stato terminato dal segnale %d, chiamato           da: %d\n", (long)siginfo->si_pid, siginfo -> si_status, getpid());

      else

       perror("Command terminated abnormally\n"); 
       
      } 
   
}

Now my question is, first: is it possibile to do it?

Second: if yes, can i do it using si_status and si_code?


Solution

  • Question resolved.

    New snippet:

    static void sigchdl (int sig, siginfo_t *siginfo, void *context)
    {
    
    
      int code = siginfo -> si_code, status = siginfo -> si_status;
    
          printf("si_code: %d\n", code);
          printf("si_status: %d\n", status);
    
    
          if(code == CLD_EXITED) { if(WIFEXITED(status)) printf("Il comando in background con PID: %ld e' terminato normalmente\n",
                (long)siginfo->si_pid); }
    
          else if(code == CLD_KILLED) {
    
           //2 = SIGINT, 9 = SIGKILL, 15 = SIGTERM
    
          if(status == 2 || status == 9 || status == 15)
    
          printf("Il comando in background con PID: %ld e' stato terminato dal segnale %d, chiamato da: %d\n",
                (long)siginfo->si_pid, siginfo -> si_status, getpid());
    
    
          }
    
          else if(code == CLD_DUMPED) perror("il comando è terminato in modo anormale \n"); 
    
    }
    

    The problem was with the WTERMSIG that resulted to be useless in the contest. Status already hold the signal constant value. si_code check is still necessary to recognize the "terminated by signal" case.

    Added CLD_DUMPED code too to recognize the abnormal interrupt of a process.