#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <signal.h> #include <math.h> #include <fcntl.h> #include <string.h> #define SIG_MUTEX 1 // prevent mutal interrupt //#undef SIG_MUTEX // Print a given set of signals void affiche_set(sigset_t set,char *msg) { puts(msg); for (int sig=0; sig<NSIG; sig++) { if (sigismember(&set,sig)) { printf("c: \tSignal %s présent\n",strsignal(sig)); } } } // To be called in a signal handler. // Protect code from being interrupted. // Show signal mask installed at signal delivery // Show pending signals while delivery void common() { sigset_t toblock, old; sigfillset(&toblock); sigprocmask(SIG_SETMASK,&toblock,&old); affiche_set(old,"c: Blocked signals"); sigset_t set; sigpending(&set); affiche_set(set,"c: Pending signals"); sigprocmask(SIG_SETMASK,&old,NULL); } // First handler (SIGUSR1) void f1(int sig) { printf("c: In %s\n",__FUNCTION__); common(); printf("c: Out %s\n",__FUNCTION__); } // Second handler (SIGUSR2) void f2(int sig) { printf("c: In %s\n",__FUNCTION__); common(); printf("c: Out %s\n",__FUNCTION__); } int main(int argc,char *argv[]) { struct sigaction action; struct sigaction action2; struct sigaction old1, old2; // Install catching before forking to ensure no race condition action.sa_handler = f1; sigemptyset(&(action.sa_mask)); #ifdef SIG_MUTEX sigaddset(&(action.sa_mask),SIGUSR2); #endif // SIG_MUTEX action.sa_flags = 0; sigaction(SIGUSR1,&action,&old1); action2.sa_handler = f2; sigemptyset(&(action2.sa_mask)); #ifdef SIG_MUTEX sigaddset(&(action2.sa_mask),SIGUSR1); #endif // SIG_MUTEX action2.sa_flags = 0; sigaction(SIGUSR2,&action2,&old2); pid_t pid = fork(); printf("%d\n",pid); int statut; switch(pid) { case 0: // child while (1) { printf("c: Do be do be doo\n"); sleep(1); } exit(0); case -1: fprintf(stderr,"Gosh! Can't demonstrate anything...\n"); exit(1); default: // ancestor // restore old behavior sigaction(SIGUSR1,&old1,NULL); sigaction(SIGUSR2,&old2,NULL); sleep(2); printf("a: sending USR1 %d\n",kill(pid,SIGUSR1)); printf("a: sending USR2 %d\n",kill(pid,SIGUSR2)); sleep(10); kill(pid,SIGTERM); pid = waitpid(0,&statut,0); if (pid==-1) { fprintf(stderr,"Gosh! something's wrong\n"); exit(1); } if (WIFEXITED(statut)) { printf("a: child %d exit status %d\n",pid,WEXITSTATUS(statut)); } if (WIFSIGNALED(statut)) { printf("a: signal %d received by child %d\n",WTERMSIG(statut),pid); } break; } exit(0); }