#include #include #include #include /* */ /* */ /*SYNOPSIS */ /* #include */ /* */ /* int sigaction ( */ /* int sig, signal to watch */ /* const struct sigaction *act, action to take */ /* struct sigaction *oact old action */ /* ); */ /* struct { */ /* void (*sa_handler)(); { SIG_DFL,SIG_IGN,address} */ /* sigset_t sa_mask; */ /* int sa_flags; */ /* } sigaction */ int counter,was_siged=0; pid_t mypid; void myhandler1(int sig, int code, struct sigcontext *spc); void myhandler2(int sig, int code, struct sigcontext *spc); void myhandler3(int sig, int code, struct sigcontext *spc); main (int argc, char * argv[]) { struct sigaction act,oact; sigset_t myset,oldset,pset; mypid = getpid(); printf ("Starting process %d \n",mypid); act.sa_handler = SIG_IGN; /* Do not need to set the mask in act.sa_mask, since it is only used if signals are caught */ if (sigaction(SIGHUP,&act,&oact)) { perror("Could not set signal handler.\n"); } act.sa_handler = &myhandler1; /* Fill the mask in act.sa_mask */ sigfillset(&(act.sa_mask)); /* Install myhandler1 as handler for SIGUSR2 and block all signals during handling */ if (sigaction(SIGUSR2,&act,&oact)) { perror("Could not set signal handler.\n"); } act.sa_handler = &myhandler2; if (sigaction(SIGINT,&act,&oact)) { perror("Could not set signal handler. \n"); } /* this is a section of code where I don't want any signals */ sigfillset(&myset); /* Set mask to myset which is full to block all signals - store original mask in oldset */ sigprocmask(SIG_SETMASK,&myset,&oldset); /* do the critical stuff */ printf ("I'm gonna take a nap go away. \n"); sleep(5); printf ("That was a nice nap. I'm back.\n"); /* Store the pending signals in pset */ sigpending(&pset); /* Test if SIGINT is one of the pending signals - if so set the handler to myhandler3, reset the mask to unblock SIGINT. If SIGINT occured it will be handled now by myhandler3. */ if (sigismember(&pset,SIGINT)) { act.sa_handler = &myhandler3; if (sigaction(SIGINT,&act,&oact)) { perror("Could not set signal handler.\n"); } sigdelset(&myset,SIGINT); sigprocmask(SIG_SETMASK,&myset,NULL); } /* Restore the old action for SIGINT and reset the mask to the old mask */ if (sigaction(SIGINT,&oact,NULL)) { perror("Could not set signal handler.\n"); } sigprocmask(SIG_SETMASK,&oldset,NULL); /* end of critical section */ printf ("Setting the counter to 0 \n"); counter = 0; while (1) { if (was_siged) { printf("Signal processed, counter : %d\n",counter); was_siged = 0; } counter++; } } void myhandler1(int sig, int code, struct sigcontext *spc) { static int count=0; printf("Caught the SIGUSR2 signal %d COUNTER is: %d \n",sig,counter); /* First time it gets called, it calls itself to show the effect of recieving a SIGUSR2 while processing a SIGUSR2 */ if (count == 0) { count++; printf ("Calling kill with sig SIGUSR2 \n"); kill(mypid,SIGUSR2); printf ("Done Calling kill with sig SIGUSR2 \n"); } was_siged = 1; } void myhandler2(int sig, int code, struct sigcontext *spc) { printf("Caught the SIGINT signal %d COUNTER is: %d \n",sig,counter); exit(0); } void myhandler3(int sig, int code, struct sigcontext *spc) { printf("You typed ^C while I was sleeping, GO AWAY.\n",sig,counter); }