clinuxsignalsposixsigchld

what is the relation between SIGTSTP and SIGCHLD


I have tow handlers for each one of them (SIGTSTP, SIGCHLD), the thing is that when I pause a process using SIGTSTP the handler function of SIGCHLD run too. what should I do to prevent this .

signal handlers :

void signalHandler(int signal) {
int pid, cstatus;
if (signal == SIGCHLD) {
    susp = 0;
    pid = waitpid(-1, &cstatus, WNOHANG);
    printf("[[child %d terminated]]\n", pid);
    DelPID(&JobsList, pid);
}
}

void ctrlZsignal(int signal){
    kill(Susp_Bg_Pid, SIGTSTP);
    susp = 0;
    printf("\nchild %d suspended\n", Susp_Bg_Pid);
}

Susp_Bg_Pid used to save the paused process id.
susp indicates the state of the "smash" the parent process if it is suspended or not .


Solution

  • Set up your SIGCHLD handler using sigaction with SA_NOCLDSTOP.

    From sigaction (2)

    SA_NOCLDSTOP - If signum is SIGCHLD, do not receive notification when child processes stop (i.e., when they receive one of SIGSTOP, SIGTSTP, SIGTTIN or SIGTTOU) or resume (i.e., they receive SIGCONT)(see wait(2)). This flag is only meaningful when establishing a handler for SIGCHLD.

    update

    void signalHandler(int sig)
    {
      //...
    }
    
    struct sigaction act;
    
    act.sa_handler = signalHandler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_NOCLDSTOP;
    
    if (sigaction(SIGCHLD, &act, 0) == -1)
    {
      perror("sigaction");
      exit(1);
    }
    

    If you aren't familiar with sigaction you should read up on it because it has several different options and behaviors that are vastly superior to signal but come at the cost of complexity and confusion before you figure out how to use it. I took my best guess at the minimum of what you seem to want to do but you'll need to learn this sooner rather than later.