I'm having some troubles using sigchld...
what I want to do is to create a child process with fork and make the child print and sleep a second for a couple of times... during these process I want to send signal to child (SIGSTOP and SIGCONTINUED) and I want the parent to print what the signal was... here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
void handler (int i) {
int x;
waitpid(-1,&x, 0);
printf("WIFSTOPPED=%d, WIFCONTINUED=%d\n", WIFSTOPPED(x),WIFCONTINUED(x) );
}
int main(){
int x;
int q=fork();
if(q==0){
int i=0;
printf("%d\n",getpid());
while (i<20){
printf("%d\n", i++);
sleep(1);
}
_exit(0);
}
else {
signal(SIGCHLD, handler);
waitpid(-1,&x, 0);
while(WIFEXITED(x)!=1){
waitpid(-1,&x, 0);
sleep(1);
}
exit(0);
}
}
but it doesn't work beacause when I send a SIGSTOP or SIGCONTINUED to the child, the child stop and continue but the parent doesn't print anything
any suggestion?
Your handler shall not call waitpid
again and you main while loop is also not correct : again you call waitpid
twice the first time. And last, your waitpid
call much declare to be interested in status changes (WUNTRACED
option).
A much correct code could be :
void handler (int i) { // a handler just handle the fact some signal occured
printf("in handler\n");
}
int main(){
int x;
int q=fork();
if(q==0){
int i=0;
printf("%d\n",getpid());
while (i<20){
printf("%d\n", i++);
sleep(1);
}
_exit(0);
}
else {
signal(SIGCHLD, handler); // catch child status changes
do {
waitpid(-1,&x, WUNTRACED|WCONTINUED); // wait until child terminates or changes its status
if (WIFSTOPPED(x)|WIFCONTINUED(x)) // test what really happens
printf("STOPPED=%d, CONTINUED=%d\n", WIFSTOPPED(x),WIFCONTINUED(x) );
} while(!WIFEXITED(x));
exit(0);
}
}