Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different signal handlers for parent and child

I have a program with a signal handler:

signal(SIGINT, signalhandler);

Then the program forks and the child needs a different signal handler so:

pid = fork();

/* What happens here? */

if(pid==0)
{
signal(SIGINT, signalhandler_for_child);
}

So what happens if a SIGINT is called right after the fork but before the new sign handler is assigned?

Can this happen or there is no possibility to be interrupted before the child gets the new signal handler.

If it is possible. How could I queue the signal to the child so it gets time to get the new handler?

I know that the probabilities, if they exist, must be almost 0, but I want to make sure the application is robust in this aspect.

like image 605
Daniel Ortega Avatar asked Mar 21 '18 10:03

Daniel Ortega


People also ask

Can you have multiple signal handlers?

Only one signal handler can be installed per signal. Only the latest installed handler will be active.

Are signal handlers inherited by children?

a child process inherits signal settings from its parent during fork (). When process performs exec (), previously ignored signals remain ignored but installed handlers are set back to the default handler.

How could you communicate between a parent and a child process?

The inter communication between a child process and a parent process can be done through normal communication schemes such as pipes, sockets, message queues, shared memories.

Are signal handlers shared across threads?

Each thread has its own signal mask. This lets a thread block some signals while it uses memory or another state that is also used by a signal handler. All threads in a process share the set of signal handlers set up by sigaction(2) and its variants.


1 Answers

So what happens if a SIGINT is called right after the fork but before the new sign handler is assigned?

The signal handler installed in the parent will be called. Child process inherits it.

Can this happen or there is no possibility to be interrupted before the child gets the new signal handler.

Cetainly can happen.

If it is possible. How could I queue the signal to the child so it gets time to get the new handler?

To ensure, you need to block SIGINT before calling fork() and then reinstall a different for SIGINT in the child process and then unblock SGINT.

/* block SIGINT here. */

pid = fork();

if (pid == 0) {
    /* Install a new SIGINT handler here. */
    /* Unblock SIGINT. */
    ...
} else if (pid > 0) {
   /* The SIGINT handler is already in place. So just unblock SIGINT. */
   ...
} else {
   /* error */
}

Look at sigprocmask() and pthread_sigmask() for blocking and unblocking signals.

You may also find the GNU documentation on signal blocking useful.

like image 73
P.P Avatar answered Nov 06 '22 04:11

P.P