Is it permissible to have multiple signal handlers for the same signal?

I have two shared libraries related to my test application. Both libraries have signal handlers for SIGINT .

Can I use multiple signal handlers for the same signal? What order of handlers will be executed when the SIGINT signal is generated?

+8
source share
5 answers

As others say, only one signal handler, which is the last, can be installed. You then have to manage the calls of the two functions yourself. The sigaction function can return a previously installed signal handler, which you can name yourself.

Something like this (unverified 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 sig handler */ sigaction(SIGINT, NULL, &old); lib1_sighandler = old.sa_handler; lib2_init(...); /* retrieve lib2 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); 
+14
source

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

+6
source

we can process several signals with one signal handler, but it is not possible to have several signal handlers for the 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 you try to run this code, u will find that the last assigned signal handler is installed for this signal. I think it is impossible to have multiple signal handlers for the same signal.

+1
source

As you can see on the sigaction man page, the new signal handler replaces the old and the old returns.

If you have two unused signals (say SIGUSR1 and SIGUSR2 ), assign these signals to two signal handlers for SIGINT . Then you can write your own signal handler for SIGINT , and from this you can raise the necessary unused signal as you wish.

+1
source

Shabaz hit a nail on the head. However, if you are looking for something that all your libraries can use (if you have access to the source code), you can do something in 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 can use it yourself, and after loading each library you will get a handler, and then call add_handler. Something like:

 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 thoughts, Anthony

+1
source

All Articles