I have been assigned the task of designing a simple web server using C in my UNIX & C class. The webserver listens and forks when a successful connection is made so that multiple clients may be served at once. The child process then handles the transaction between client and server. I am now required to implement code that handles signals, specifically SIGTERM and SIGQUIT.
On receipt of either of these signals the program must signal any active children to terminate. If they do not respond in a timely manner the program must then send the SIGKILL signal to kill them. I am assuming that the “program” in this context refers to the parent process of all active children (which I believe is the process active before the invocation of fork()). I am also assuming that these signals have to be trapped. So my plan is to have a signal handler for each one.
My questions are:
1. How can I signal all active children to terminate?
2. How does the parent know when the child processes have terminated (and therefore know when to send the KILL signal)?
My only thoughts on answering the first question is to use a signal handler to set a flag which on return only redirects the flow of execution within the child exclusive code and doesn’t affect the parent. The only problem though is that the child could be currently serving a client and so won’t immediately terminate until it reaches the flag.
Any help is greatly appreciated
2
I recommend you to store the child process PID in an array, to eventually, send the signal in this way.
for(i=0; i<number_of_child; i++){
if(kill(PID_child[i], SIGTERM) == -1 && errno != ESRCH){
/*Free resources*/
exit(EXIT_FAILURE);
}
}
/*Do not let zombies alive(wait for all the child to finish)
with this the parent know that the child has finished successfully*/
while(wait(NULL) != -1 || errno == EINTR);
With this code, you can kill all the child processes, if you want to make more things, I encourage you to try to make your own handler. These man pages will help you:
- http://man7.org/linux/man-pages/man7/signal.7.html (man 7 signal)
- http://man7.org/linux/man-pages/man2/sigaction.2.html (man sigaction)
Other option is to use the function killpg()
which will send the signal to the whole tree of processes(including the father) but in my opinion it is more complex.