/*---------------------------------------------------------------------+ | 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) { sigset_t setsig, /* Initial signal mask */ newsetsig; /* Second signal mask */ pid_t pid = getpid (); /* Process ID (of this process) */ /* Print out program header */ printf ("%s: IPC TestSuite program\n\n", *argv); /* * Establish signal handler for each signal & reset "valid signals" * array */ init_sig (); reset_valid_sig (); sigemptyset(&setsig); if (sigprocmask (SIG_SETMASK, &setsig, (sigset_t *) NULL) < 0) sys_error ("sigprocmask failed", __LINE__); /* * 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 initialize the signal set so that all signals are excluded, * then individually add the signals to block to the signal set. * * Then change the process signal mask with sigprocmask (SIG_SETMASK). * * 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(&setsig); if (sigaddset (&setsig, SIGIOT) < 0) sys_error ("sigaddset (SIGIOT) failed", __LINE__); if (sigaddset (&setsig, SIGILL) < 0) sys_error ("sigaddset (SIGILL) failed", __LINE__); if (sigaddset (&setsig, SIGALRM) < 0) sys_error ("sigaddset (SIGALRM) failed", __LINE__); if (sigprocmask (SIG_SETMASK, &setsig, (sigset_t *) NULL) < 0) sys_error ("sigaddset (SIGALRM) failed", __LINE__); 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]) sys_error ("failed to receive SIGFPE signal!", __LINE__); if (valid_sig [SIGTERM]) sys_error ("failed to receive SIGTERM signal!", __LINE__); if (valid_sig [SIGINT]) sys_error ("failed to receive SIGINT signal!", __LINE__); /* * Block additional SIGFPE, SIGTERM & SIGINT signals: * * Create an other signal set to contain the additional signals to block * and add the signals to block to the signal set. * * Change the process signal mask to block the additional signals * with the sigprocmask (SIG_BLOCK) 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 (&newsetsig); sigaddset (&newsetsig, SIGFPE); sigaddset (&newsetsig, SIGTERM); sigaddset (&newsetsig, SIGINT); if (sigprocmask (SIG_BLOCK, &newsetsig, &setsig) < 0) sys_error ("sigprocmask failed", __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 specifiy a new process signal set to allow the SIGINT signal * to interrupt the process. Create the signal set by initializing * the signal set with sigfillset () so that all signals are included * in the signal set, then remove the SIGINT signal from the set with * sigdelset (). * * Force the process to suspend execution until delivery of an * unblocked signal (SIGINT in this case) with sigsuspend (). * * Additionally, verify that the SIGINT signal was received. */ valid_sig [SIGINT] = 1; printf ("\n\tChange signal mask & wait until signal interrupts process\n"); if (sigfillset (&setsig) < 0) sys_error ("sigfillset failed", __LINE__); if (sigdelset (&setsig, SIGINT) < 0) sys_error ("sigdelset failed", __LINE__); if (sigsuspend(&setsig) != -1 || errno != 4) sys_error ("sigsuspend failed", __LINE__); if (valid_sig [SIGINT]) error ("failed to receive SIGIOT signal!", __LINE__); /* Program completed successfully -- exit */ printf ("\nsuccessful!\n"); return (0); }