/*---------------------------------------------------------------------+ | main () | | ==================================================================== | | | | Function: Main program (see prolog for more details) | | | +---------------------------------------------------------------------*/ int main(int argc, char **argv) { sigset_t mask, /* Initial process signal mask */ newmask, /* Second process signal mask */ oldmask; /* Signal mask returned by sigblock */ pid_t pid = getpid(); /* Process ID (of this process) */ /* Print out program header */ printf("%s: IPC Signals TestSuite program\n\n", *argv); /* * Establish signal handler for each signal & reset "valid signals" * array, and setup alternative stack for processing signals */ init_sig_vec(); reset_valid_sig(); #ifdef _LINUX_ // sigstack function is obsolete, use sigaltstack instead if (sigaltstack(&stack, NULL) < 0) sys_error("sigaltstack failed", __LINE__); #else if (sigstack(&stack, NULL) < 0) sys_error("sigstack failed", __LINE__); #endif /* * Send SIGILL, SIGALRM & SIGIOT signals to this process: * * First indicate which signals the signal handler should expect * by setting the corresponding valid_sig[] array fields. * * Then send the signals to this process. * * And finally verify that the signals were caught by the signal * handler by checking to see if the corresponding valid_sig[] array * fields were reset. */ printf("\tSend SIGILL, SIGALRM, SIGIOT signals to process\n"); valid_sig[SIGILL] = 1; valid_sig[SIGALRM] = 1; valid_sig[SIGIOT] = 1; kill(pid, SIGILL); kill(pid, SIGALRM); kill(pid, SIGIOT); if (valid_sig[SIGILL]) error("failed to receive SIGILL signal!", __LINE__); if (valid_sig[SIGALRM]) error("failed to receive SIGALRM signal!", __LINE__); if (valid_sig[SIGIOT]) error("failed to receive SIGIOT signal!", __LINE__); /* * Block SIGILL, SIGALRM & SIGIOT signals: * * First create the process signal mask by ORing together the * signal values. * * Then change the process signal mask with sigsetmask (). * * Verify that the desired signals are blocked from interrupting the * process, by sending both blocked and unblocked signals to the * process. Only the unblocked signals should interrupt the process. */ printf("\n\tBlock SIGILL, SIGALRM, SIGIOT signals, " "and resend signals + others\n"); sigemptyset(&mask); sigaddset(&mask, SIGILL); sigaddset(&mask, SIGALRM); sigaddset(&mask, SIGIOT); #ifdef _LINUX_ sigprocmask(SIG_SETMASK, &mask, NULL); #else if (sigsetmask(mask) < 0) sys_error("setsigmask failed", __LINE__); #endif valid_sig[SIGFPE] = 1; valid_sig[SIGTERM] = 1; valid_sig[SIGINT] = 1; kill(pid, SIGILL); kill(pid, SIGALRM); kill(pid, SIGIOT); kill(pid, SIGFPE); kill(pid, SIGTERM); kill(pid, SIGINT); if (valid_sig[SIGFPE]) error("failed to receive SIGFPE signal!", __LINE__); if (valid_sig[SIGTERM]) error("failed to receive SIGTERM signal!", __LINE__); if (valid_sig[SIGINT]) error("failed to receive SIGINT signal!", __LINE__); /* * Block additional SIGFPE, SIGTERM & SIGINT signals: * * Create a signal mask containing the additional signals to block. * * Change the process signal mask to block the additional signals * with the sigprocmask () function. * * Verify that all of the desired signals are now blocked from * interrupting the process. None of the specified signals should * interrupt the process until the process signal mask is changed. */ printf("\n\tBlock rest of signals\n"); sigemptyset(&newmask); sigaddset(&newmask, SIGFPE); sigaddset(&newmask, SIGTERM); sigaddset(&newmask, SIGINT); sigemptyset(&oldmask); if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) { perror("sigprocmask failed"); exit(-1); } if (memcmp(&mask, &oldmask, sizeof(mask)) != 0) error("value returned by sigblock () does not match the " "old signal mask", __LINE__); kill(pid, SIGILL); kill(pid, SIGALRM); kill(pid, SIGIOT); kill(pid, SIGFPE); kill(pid, SIGTERM); kill(pid, SIGINT); /* Wait two seconds just to make sure that none of the specified * signals interrupt the process (They should all be blocked). */ sleep(2); /* Change the process signal mask: * * Now allow the SIGINT signal to interrupt the process. * Thus by using sigpause (), force the process to suspend * execution until delivery of an unblocked signal (here SIGINT). * * Additionally, verify that the SIGINT signal was received. */ valid_sig[SIGINT] = 1; printf ("\n\tChange signal mask & wait until signal interrupts process\n"); if (sigpause(SIGINT) != -1 || errno != 4) sys_error("sigpause failed", __LINE__); if (valid_sig[SIGINT]) error("failed to receive SIGINT signal!", __LINE__); /* Program completed successfully -- exit */ printf("\nsuccessful!\n"); return (0); }
/*---------------------------------------------------------------------+ | main () | | ==================================================================== | | | | Function: Main program (see prolog for more details) | | | +---------------------------------------------------------------------*/ int main (int argc, char **argv) { int timeout = MAXTIME*60; /* Number sec to wait for signal */ /* Print out program header */ printf ("%s: IPC Signals TestSuite program\n\n", *argv); /* Set up our signal handlers */ init_sig_vec (); /* * Critical section - block SIGILL signal * * Block the SIGILL interrupt from interrupting the process * with the sigprocmask () system function call. * * Send the SIGILL interrupt to the process in an attempt to * disrupt the critial section -- the signal should be blocked. * Wait one second to insure that the signal has plenty of time * to reach the process. */ #ifdef _LINUX_ sigset_t mask; sigemptyset (&mask); sigaddset (&mask, SIGILL); sigprocmask (SIG_BLOCK, &mask, NULL); #else if (sigblock ( MASK (SIGILL) ) < 0) sys_error ("sigblock failed", __LINE__); #endif printf ("\t(BEGIN) Critial section\n"); /* Critial section */ sleep (1); /* * End of critical section - ensure SIGILL signal was not received * * Check to insure that the signal handler has not caught any signals, * and then unblock all of the signals with the sigsetmask system * function call. */ if (signals_received > 0) error ("received an unexpected signal during the critical section", __LINE__); printf ("\n\t(END) Critial section\n"); #ifdef _LINUX_ sigemptyset (&mask); sigprocmask (SIG_SETMASK, &mask, NULL); #else if (sigsetmask (0) < 0) sys_error ("sigsetmask failed", __LINE__); #endif raise (SIGILL); /* * Upon unblocking the signals, should receive the SIGILL signal. * Verify that it indeed is caught. */ while (signals_received == 0 && --timeout) { printf("."); fflush(stdout); sleep (1); } if (timeout == 0) error ("failed to receive SIGILL signal after unblocking signals", __LINE__); /* Program completed successfully -- exit */ printf ("\nsuccessful!\n"); return (0); }