I'm working on a Linux application that creates several subprograms using the system call fork(). The idea is that the father program sends the children program the signal SIGUSR2, and they get blocked. In order to do that, we have to modify the SIGUSR2 interception function in the children.
(Signal interception function)
1 2 3 4 5 6 7 8 9 10
void resp_SIGUSR2 (int n, siginfo_t * info , void * p){
if (pid == 0){ //Pid is a global variable. If 0, the process is a children
sigset_t masc;
sigfillset(&masc); //We add every signal to the masc set
sigdelset(&masc,SIGUSR1);// We delete SIGUSR1 from it
sigsuspend(&masc); // We suspend the child process. Every signal is masked
// excepting SIGUSR1 , and the non-mascarable ones
}
}
My problem is that, despite the children gets blocked (I've checked using ps -lejH on another terminal), the father gets stuck at this waitpid call, as if no children had changed their state.
1 2 3 4 5 6 7 8
//This is called in the father everytime the father sends SIGUSR2 to a particular child
if (waitpid( (pid_t) pid_child, &(sp.siginfo), WUNTRACED|WCONTINUED)==pid_child){
cout << "State changed successfully \n";
}
else{
cout << "*ERROR! " << pid_child<<" didn't receive the signal correctly\n";
}
What is going on here? Why is waitpid() apparently not working? What am I doing wrong?
Thanks in advance for your help.
I meant to delete SIGUSR2, and not SIGUSR1, and that's what i did. I masked every signal, and then, removed SIGUSR1 from that mask, so SIGUSR1 is not masked.
SIGUSR2 is the "go to sleep" signal. SIGUSR1 is the "wake up" signal. sigsuspend(&masc); suspends the process and uses the mask "masc" UNTIL somebody wakes it up sending SIGUSR1. The mask is then removed.
Have you run the parent through a debugger, like strace?
No, that does not work, and wouldn't have .I'll explain you why. I did some more research, and asked some of my lecturers about this issue. It seems that waitpid doesn't detect every possible state change. For instance, it does not detect the state changeRunning -> Suspended . According to Linux Programmer's Manual http://man.cx/waitpid%282%29 ,
A state change is considered to be: the child terminated; the child was stopped by a signal; or the child was resumed by a signal.
In order to keep track of every state change we can check the file /proc/pid/stat , where pid is the pid of the process you want to keep watch on.
EDIT: Oh, I almost forgot!. You must execute the program in super user mode ( sudo <program_name>), otherwise it won't be able to access the /proc folder.