Lois2B
Lois2B

Reputation: 121

Fork() child processes with signals

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

Answers (1)

David W.
David W.

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

Related Questions