Gestionnaire de signal pour tous les signaux

Comment puis-je enregistrer un gestionnaire de signal pour tout le signal, disponible sur le système d’exploitation en cours, en utilisant le signal (3)?

Mon code ressemble à ceci:

void sig_handler(int signum) { printf("Received signal %d\n", signum); } int main() { signal(ALL_SIGNALS_??, sig_handler); while (1) { sleep(1); }; return 0; } 

La plupart des systèmes ont une macro NSIG ou _NSIG (le premier ne serait pas disponible en mode de conformité aux normes car il viole l’espace de nommage) défini dans le signal.h telle sorte qu’une boucle for (i=1; i<_NSIG; i++) signaux. De plus, sur les systèmes POSIX dotés de masques de signal, CHAR_BIT*sizeof(sigset_t) est une limite supérieure du nombre de signaux que vous pouvez utiliser comme NSIG repli si ni NSIG ni _NSIG sont définis.

Les gestionnaires de signaux doivent faire face aux problèmes de réentrance et à d’autres problèmes. En pratique, il est souvent plus pratique de masquer les signaux et de les récupérer de temps en temps. Vous pouvez masquer tous les signaux (sauf SIGSTOP et SIGKILL , que vous ne pouvez pas gérer de toute façon) avec ceci:

 sigset_t all_signals; sigfillset(&all_signals); sigprocmask(SIG_BLOCK, &all_signals, NULL); 

Le code est légèrement différent si vous utilisez pthreads. Appelez ceci dans chaque thread, ou (de préférence) dans le thread principal avant de créer d’autres:

 sigset_t all_signals; sigfillset(&all_signals); pthread_sigmask(SIG_BLOCK, &all_signals, NULL); 

Une fois que vous avez fait cela, vous devriez appeler périodiquement sigtimedwait(2) comme ceci:

 struct timespec no_time = {0, 0}; siginfo_t result; int rc = sigtimedwait(&all_signals, &result, &no_time); 

Si un signal est en attente, les informations à son sujet seront placées dans result et rc sera le numéro du signal; sinon, rc sera -1 et errno sera EAGAIN . Si vous appelez déjà select(2) / poll(2) (par exemple dans le cadre d’un système piloté par les événements), vous pouvez créer un signalfd(2) place et le joindre à votre boucle d’événement. Dans ce cas, vous devez toujours masquer les signaux comme indiqué ci-dessus.