Is it valid to have multiple signal handlers for same signal?

20,724

Solution 1

As said by others, only one signal handler can be set, which is the last one. You would then have to manage calling two functions yourself. The sigaction function can return the previously installed signal handler which you can call yourself.

Something like this (untested code):

/* other signal handlers */
static void (*lib1_sighandler)(int) = NULL;
static void (*lib2_sighandler)(int) = NULL;

static void aggregate_handler(int signum)
{
    /* your own cleanup */
    if (lib1_sighandler)
        lib1_sighandler(signum);
    if (lib2_sighandler)
        lib2_sighandler(signum);
}

... (later in main)
struct sigaction sa;
struct sigaction old;

lib1_init(...);
/* retrieve lib1's sig handler */
sigaction(SIGINT, NULL, &old);
lib1_sighandler = old.sa_handler;

lib2_init(...);
/* retrieve lib2's sig handler */
sigaction(SIGINT, NULL, &old);
lib2_sighandler = old.sa_handler;

/* set our own sig handler */
memset(&sa, 0, sizeof(sa));
sa.sa_handler = aggregate_handler;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);

Solution 2

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

Solution 3

As you could see in the man page for sigaction, the new signal handler replaces the old one and the old one is returned.

If you have two unused signals (say SIGUSR1 and SIGUSR2), assign those signals the two signal handlers for SIGINT. Then you may write your own Signal Handler for SIGINT and from that, you may raise the needed unused signal as per you want.

Solution 4

Shabaz hit the nail on the head. However, if you're looking for something all your libraries could use (provided you have access to the source code), you could do something along the following lines:

linked_list* sigint_handlers = NULL;

void sighand_init(sighand_config_t* config) {
    struct sigaction action;
    memset(&signalaction, 0, sizeof(signalaction));
    action.sa_handler = &sighand_main;

    // Order is important, in case we get a signal during start-up
    sigint_handlers = linked_list_new();
    sigaction(SIGINT, &action);
}

void sighand_main(int signum) {
    if (signum == SIGINT) {
        linked_list_node* node = linked_list_head(sigint_handlers);
        while ((node = node->next) != NULL) {
            node->object(signum);
        }
        if (sighand_config.exitonint) {
            app_exit(0);
        }
    }
}

void sighand_add_int_handler(void (*handler)(int)) {
    if (handler == NULL) return;
    linked_list_add(sigint_handlers, handler);
}

void sighand_destroy() {
    ...
    linked_list_destroy(signint_handlers);
    ...
}

Or, you could use this yourself, and after loading each library, get the handler and later call add_handler. Something along the lines of:

loadlibrary(lib1.so);
sigaction1 = signalget(SIGINT);

loadlibrary(lib2.so);
sigaction2 = signalget(SIGINT);

sighand_init(...);
sighand_add_int_handler(sigaction1.sa_handler);
sighand_add_int_handler(sigaction2.sa_handler);

Just some thoughts, Anthony

Solution 5

we can handle multiple signal with single signal handler but but its is not possible to have multiple signal handler for same signal.

void sig_handler(int signo)
{
if (signo == SIGINT)
printf("received SIGINT 1\n"); 
}
void sig(int signo)
{
     if (signo == SIGINT)
        printf("received SIGINT 2\n");
}
   int main(void)
  {
      if(signal(SIGINT, sig_handler) == SIG_ERR)
          printf("\ncan't catch SIGINT\n");

      if (signal(SIGINT, sig) == SIG_ERR)
          printf("\ncan't catch SIGINT\n");
  // A long long wait so that we can easily issue a signal to this process
     while(1) 
       sleep(1);
     return 0;
  }

if u try to run this code u will find that the last assigned signal handler is set for that signal. i think it is not possible to have a multiple signal handler for same signal.

Share:
20,724

Related videos on Youtube

Lunar Mushrooms
Author by

Lunar Mushrooms

Updated on March 15, 2020

Comments

  • Lunar Mushrooms
    Lunar Mushrooms about 4 years

    I have two shared libraries linked to my test application. Both of the libraries have signal handlers for SIGINT.

    Is it valid to have multiple signal handlers for same signal? Which order the handlers will execute when I generate a SIGINT signal?

  • raj raj
    raj raj almost 11 years
    Do we miss a return; in if (lib1_sighandler) block?
  • Shahbaz
    Shahbaz almost 11 years
    @rajraj, no, why? We need to call both handlers. The if only makes sure the pointers are not NULL. Just in case, since you don't want to crash inside a signal handler.