// File :sigmenu.cpp // Menu driven program to demonstrate sigprocmask(), sigaction() and ? // sigsuspend & sigpending, along with masks and other stuff. // User is allowed to specify signals to block, catch, or suspend. After the // request, the signal will be sent to itself to see what happens. // The previous action for all signals will be maintained. // Stop this program using kill -9 #include #include #include #include #include #define period 3 using namespace std; char menu(); void getSignal(int &); void handler(int); main() {struct sigaction defaultAction[32],action; sigset_t sigset,oldset,pendingset; // First, set up default action array. For each signal, reset it's action, // which places the default action into the 3rd argument of sigaction() // Put the action to be the handler. action.sa_handler = (void (*)(int))handler; int i; for (i=1;i<32;i++) { if (sigaction(i,&action,&defaultAction[i])<0) { cerr << i << " couldn't be caught\n"; } // Now, restore the default action if (sigaction(i,&defaultAction[i],NULL)<0) { cerr << i << " couldn't be reset to its default\n"; } } int signalNum; char choice; // Empty out the signal set sigemptyset(&sigset); do { choice=menu(); if (choice=='B' || choice=='C' || choice=='S') getSignal(signalNum); switch (choice) { case 'B': sigaddset(&sigset,signalNum); sigprocmask(SIG_BLOCK,&sigset,&oldset); cout << "Mask set. Signal will be issued in 1 second\n"; sleep(1); kill(getpid(),signalNum); cout << "Check what's pending..."; sigpending(&pendingset); for (i=1;i<32;i++) if (sigismember(&pendingset,i)) cout << i << " "; cout << endl; cout << "Now, the signal will be unblocked...\n"; sigprocmask(SIG_UNBLOCK,&sigset,&oldset); // Restore sigset sigdelset(&sigset,signalNum); break; case 'C': cout << "The handler will be set...\n"; sigaction(signalNum,&action,NULL); cout << "The signal will be sent in 1 second\n"; sleep(1); kill(getpid(),signalNum); cout << "And, we're back...Default action restored\n"; if (sigaction(signalNum,&defaultAction[signalNum],NULL)<0) { cerr << i << " couldn't be reset to its default\n"; } break; } } while (choice !='Q'); } char getChoice(char *ok) {char ch; do ch=toupper(cin.get()); while (strchr(ok,ch)==NULL); return(toupper(ch)); } char menu() {cout << "\n===================================================\n"; cout << "Enter Choice:\n"; cout << "B)lock a signal\n"; cout << "C)atch a signal\n"; cout << "Q)uit\n"; cout << "===================================================\n"; return(getChoice("BCQ")); } void getSignal(int &theSignal) {cout << "Enter the signal number, a value in range [1,31] >"; cin >> theSignal; } void handler(int sig) {fprintf(stderr,"Caught Signal %d\n",sig); }