Reputation: 121
I have to fork two child processes in which the SIGINT command is blocked, but one of them should unblock it when receiving a SIGTERM signal, while the other child process and the parent both print their PID's as a result of the same SIGTERM signal. The second child process should terminate right away, but the parent process shall wait for its child processes to end and then stop.
I just started to learn C programming in Linux, and I don't really understand how forking and signals work. As far as I understand, this code I've written so far will fork a process, and the child will block the Ctrl-C command, and the whole thing will run forever unless I kill it with kill -9 pid.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
void handler(int n) {
write(STDOUT_FILENO, "I won't die!! Haha\n",13);
}
int main()
{
pid_t pid = fork();
if (pid < 0) {
perror("Fork() error!");
exit(-1);
}
if (pid == 0)
signal(SIGINT,handler);
while(1) {
printf("Wasting the iteration. %d\n", getpid());
sleep(1);
}
return 0;
}
Upvotes: 0
Views: 1833
Reputation: 383
Not sure about forking multiple processes as I've never done that. In terms of SIGTERM, you need a callback to handle a termination signal. The following is one I use in many of the services I write:
/***************************************************************************************************
* Function signal_callback_handler - allows for a graceful shutdown process.
* *************************************************************************************************/
void signal_callback_handler(int signum) {
//here we receive some sort of notification to terminate.
//Log this event and change the state of the process control variable
//so that the main processing loop knows to stop
syslog(LOG_NOTICE, "Recived signal to shutdown - Signal %d", signum);
//put code here to do preshutdown clean up, terminating threads, etc....
}
Then you need to register the callback for each termination signal you want to deal with. The following are ones I place in my main function before I fork:
if (signal(SIGINT, signal_callback_handler) == SIG_ERR) {
syslog(LOG_CRIT, "An error occurred while setting SIGINT signal handler.");
return(EXIT_FAILURE);
}
if (signal(SIGUSR1, signal_callback_handler) == SIG_ERR) {
syslog(LOG_CRIT, "An error occurred while setting SIGUSR1 signal handler.");
return(EXIT_FAILURE);
}
if (signal(SIGUSR2, signal_callback_handler) == SIG_ERR) {
syslog(LOG_CRIT, "An error occurred while setting SIGUSR signal handler.");
return(EXIT_FAILURE);
}
if (signal(SIGTERM, signal_callback_handler) == SIG_ERR) {
syslog(LOG_CRIT, "An error occurred while setting SIGTERM signal handler.");
return(EXIT_FAILURE);
}
if (signal(SIGTSTP, signal_callback_handler) == SIG_ERR) {
syslog(LOG_CRIT, "An error occurred while setting SIGTSTP signal handler.");
return(EXIT_FAILURE);
}
Upvotes: 0