// signal.C #include "common.h" /* this includes "signall.h" */ #include "message.h" #include #include #include #include #include "common.h" #ifdef MERGE extern int OutputBufferLen; extern char * OutputBuffer; extern void do_storage(char *, int); #endif extern pid_t Masterpid; extern pid_t Mergepid; int Signal=0; int Location = 0; int sigwakeup_occurred = 0; int sigusr1_occurred = 0; int sigusr2_occurred = 0; int sigint_occurred = 0; int sigterm_occurred = 0; int signal_occurred = 0; // the (trival) POSIX signal handlers void sigwakeup_received (int signo) { sprintf(message_buffer, "POSIX signal handler received wakeup signal"); report_message(MSG_TRACE); Signal = signo; signal_occurred++; sigwakeup_occurred++; } void sigusr1_received (int signo) { sprintf(message_buffer, "POSIX signal handler received USR1 signal"); report_message(MSG_TRACE); Signal = signo; signal_occurred++; sigusr1_occurred++; } void sigusr2_received (int signo) { sprintf(message_buffer, "POSIX signal handler received USR2 signal"); report_message(MSG_TRACE); Signal = signo; signal_occurred++; sigusr2_occurred++; } void sigint_received (int signo) { sprintf(message_buffer, "POSIX signal handler received INT signal"); report_message(MSG_TRACE); Signal = signo; signal_occurred++; sigint_occurred++; } void sigterm_received (int signo) { sprintf(message_buffer, "POSIX signal handler received TERM signal"); report_message(MSG_TRACE); #ifdef MERGE (void) do_storage (OutputBuffer, OutputBufferLen); // ********************************************** printf("TERM output current data buffer\n"); #endif Signal = signo; signal_occurred++; sigterm_occurred++; } void sig_received (int signo) { sprintf(message_buffer, "sig_received received %d.",signo); report_message(MSG_TRACE); Signal = signo; if (Signal == SIGSEGV) { #ifdef MERGE sprintf(message_buffer, "Received SEGV signal: Location %d (0x%0x); exiting.", Location, Location); #else sprintf(message_buffer, "Received SEGV signal; exiting."); #endif report_message(MSG_FAILURE); exit(0); } if (Signal == SIGBUS) { sprintf(message_buffer, "Received BUS signal; exiting."); report_message(MSG_FAILURE); exit(0); } if (Signal == SIGTERM) { sprintf(message_buffer, "Received TERM signal; exiting."); report_message(MSG_FAILURE); exit(0); } if (Signal == SIGINT) { sprintf(message_buffer, "Received INT signal; exiting."); report_message(MSG_FAILURE); exit(0); } sprintf(message_buffer, "Received signal %d.",signo); report_message(MSG_TRACE); #ifdef MASTER sprintf(message_buffer, "Task terminating."); report_message(MSG_FAILURE); exit(0); #endif } void signal_block () { sigset_t signalSet; // mask off signals handled by the main thread sigemptyset(&signalSet); sigaddset(&signalSet, SIGTERM); sigaddset(&signalSet, SIGINT); sigaddset(&signalSet, SIGWAKEUP); sigaddset(&signalSet, SIGUSR1); sigaddset(&signalSet, SIGUSR2); sigprocmask(SIG_BLOCK, &signalSet, NULL); } void sig_init () { // install required signal handlers sprintf(message_buffer, "install required signal handlers (%d %d).", SIGRTMIN, SIGRTMAX); report_message(MSG_TRACE); int i; struct sigaction sa; for (i=SIGHUP; i< SIGRTMIN; i++) { if (i==SIGPROF) continue; if (i==SIGWINCH) continue; sa.sa_handler = sig_received; sigemptyset(&sa.sa_mask); sa.sa_flags=0; (void) sigaction(i, &sa, NULL); } signal_occurred = 0; sigusr1_occurred = 0; sa.sa_handler = sigusr1_received; sigemptyset(&sa.sa_mask); sa.sa_flags=0; if (sigaction(SIGUSR1, &sa, NULL)) { sprintf(message_buffer, "Unable to setup signal handler for SIGUSR1 - This must be fixed - exiting."); report_message(MSG_FAILURE); exit(1); } sprintf(message_buffer, "installed signal handler for SIGUSR1 (%d).", SIGUSR1); report_message(MSG_TRACE); signal_occurred = 0; sigusr2_occurred = 0; sa.sa_handler = sigusr2_received; sigemptyset(&sa.sa_mask); sa.sa_flags=0; if (sigaction(SIGUSR2, &sa, NULL)) { sprintf(message_buffer, "Unable to setup signal handler for SIGUSR2 - This must be fixed - exiting."); report_message(MSG_FAILURE); exit(1); } sprintf(message_buffer, "installed signal handler for SIGUSR2 (%d).", SIGUSR2); report_message(MSG_TRACE); signal_occurred = 0; sigterm_occurred = 0; sa.sa_handler = sigterm_received; sigemptyset(&sa.sa_mask); sa.sa_flags=0; if (sigaction(SIGTERM, &sa, NULL)) { sprintf(message_buffer, "Unable to setup signal handler for SIGTERM - This must be fixed - exiting."); report_message(MSG_FAILURE); exit(1); } sprintf(message_buffer, "installed signal handler for SIGTERM (%d).", SIGTERM); report_message(MSG_TRACE); signal_occurred = 0; sigint_occurred = 0; sa.sa_handler = sigint_received; sigemptyset(&sa.sa_mask); sa.sa_flags=0; if (sigaction(SIGINT, &sa, NULL)) { sprintf(message_buffer, "Unable to setup signal handler for SIGINT - This must be fixed - exiting."); report_message(MSG_FAILURE); exit(1); } sprintf(message_buffer, "installed signal handler for SIGINT (%d).", SIGINT); report_message(MSG_TRACE); signal_occurred = 0; sigwakeup_occurred = 0; sa.sa_handler = sigwakeup_received; sigemptyset(&sa.sa_mask); sa.sa_flags=0; if (sigaction(SIGWAKEUP, &sa, NULL)) { sprintf(message_buffer, "Unable to setup signal handler for SIGWAKEUP - This must be fixed - exiting."); report_message(MSG_FAILURE); exit(1); } sprintf(message_buffer, "installed signal handler for SIGWAKEUP (%d).", SIGWAKEUP); report_message(MSG_TRACE); } #ifdef LINK // send wakeup signal to the Merge task int wakeup_merge () { int err=0; err = kill(Mergepid, SIGWAKEUP); if (err == 0) { sprintf(message_buffer, "wakeup_merge sent signal SIGWAKEUP (%d)",SIGWAKEUP); report_message(MSG_TRACE); } else { sprintf(message_buffer, "failed to send signal SIGWAKEUP to Merge Task %d - %s", Mergepid, strerror(errno)); report_message(MSG_WARNING); } return(err); } #endif #ifdef MASTER // send wakeup signal to a Link task int wakeup_link (int pid) { int err=0; err = kill(pid, SIGWAKEUP); if (err == 0) { sprintf(message_buffer, "wakeup_link sent signal SIGWAKEUP (%d)",SIGWAKEUP); report_message(MSG_TRACE); } else { sprintf(message_buffer, "failed to send signal SIGWAKEUP to Link Task %d - %s", pid, strerror(errno)); report_message(MSG_WARNING); } return(err); } #endif #ifndef MASTER // send wakeup signal to the Merger Master int wakeup_master () { int err=0; err = kill(Masterpid, SIGUSR1); if (err == 0) { sprintf(message_buffer, "wakeup_master sent signal SIGUSR1"); report_message(MSG_TRACE); } else { sprintf(message_buffer, "failed to send signal SIGUSR1 to Master Task %d - %s", Masterpid, strerror(errno)); report_message(MSG_WARNING); } return(err); } #endif #ifdef MASTER void sig_handler (int sig) { trace("sig_handler entered"); if (sig == SIGUSR1) { sprintf(message_buffer, "received signal %d.", sig); report_message(MSG_TRACE); trace("sig_handler left"); return; } if (sig == SIGUSR2) { sprintf(message_buffer, "received signal %d.", sig); report_message(MSG_TRACE); trace("sig_handler left"); return; } if (sig == SIGINT) { sprintf(message_buffer, "received signal %d.", sig); report_message(MSG_TRACE); trace("sig_handler left"); return; } if (sig == SIGWAKEUP) { sprintf(message_buffer, "received signal %d.", sig); report_message(MSG_TRACE); trace("sig_handler left"); return; } if (sig == SIGTERM || sig == SIGINT) { sprintf(message_buffer, "received signal %d.", sig); report_message(MSG_TRACE); // terminate signal sprintf(message_buffer,"%s","Task terminating."); report_message(MSG_FAILURE); exit(0); } sprintf(message_buffer, "Unexpected signal %d.", sig); report_message(MSG_WARNING); } #endif #ifdef MERGE int wait_for_wakeup () { sigset_t newsignalSet; sigset_t oldsignalSet; report_message(MSG_TRACE); if (signal_occurred == 0) { sigemptyset(&newsignalSet); sigaddset(&newsignalSet,SIGWAKEUP); sigaddset(&newsignalSet,SIGUSR1); sigaddset(&newsignalSet,SIGUSR2); sigprocmask(SIG_BLOCK,&newsignalSet,&oldsignalSet); } if (signal_occurred == 0) { sigdelset(&oldsignalSet,SIGWAKEUP); sigdelset(&oldsignalSet,SIGUSR1); sigdelset(&oldsignalSet,SIGUSR2); (void) sigsuspend(&oldsignalSet); } sprintf(message_buffer, "wakeup occurred: %d, %d, %d, %d", signal_occurred, sigusr1_occurred, sigusr2_occurred, sigwakeup_occurred); report_message(MSG_TRACE); signal_occurred--; if (sigusr1_occurred > 0) { sigusr1_occurred--; Signal = SIGUSR1; sprintf(message_buffer, "Received USR1 signal"); report_message(MSG_TRACE); } else if (sigusr2_occurred > 0) { sigusr2_occurred--; Signal = SIGUSR2; sprintf(message_buffer, "Received USR2 signal"); report_message(MSG_TRACE); } else if (sigwakeup_occurred > 0) { sigwakeup_occurred--; Signal = SIGWAKEUP; sprintf(message_buffer, "Received wakeup signal"); report_message(MSG_TRACE); } else if (sigterm_occurred > 0) { sigterm_occurred--; Signal = SIGTERM; sprintf(message_buffer, "Received term signal"); report_message(MSG_TRACE); } else { Signal = 0; // unexpected event sprintf(message_buffer, "Received unexpected signal"); report_message(MSG_WARNING); } return (Signal); } #endif #ifdef MASTER int wait_for_wakeup () { sigset_t newsignalSet; sigset_t oldsignalSet; report_message(MSG_TRACE); if (signal_occurred == 0) { sigemptyset(&newsignalSet); sigaddset(&newsignalSet,SIGWAKEUP); sigaddset(&newsignalSet,SIGUSR1); sigaddset(&newsignalSet,SIGUSR2); sigprocmask(SIG_BLOCK,&newsignalSet,&oldsignalSet); } if (signal_occurred == 0) { sigdelset(&oldsignalSet,SIGWAKEUP); sigdelset(&oldsignalSet,SIGUSR1); sigdelset(&oldsignalSet,SIGUSR2); (void) sigsuspend(&oldsignalSet); } sprintf(message_buffer, "wakeup occurred: %d, %d, %d, %d", signal_occurred, sigusr1_occurred, sigusr2_occurred, sigwakeup_occurred); report_message(MSG_TRACE); signal_occurred--; if (sigusr1_occurred > 0) { sigusr1_occurred--; Signal = SIGUSR1; sprintf(message_buffer, "Received USR1 signal"); report_message(MSG_TRACE); } else if (sigusr2_occurred > 0) { sigusr2_occurred--; Signal = SIGUSR2; sprintf(message_buffer, "Received USR2 signal"); report_message(MSG_TRACE); } else if (sigwakeup_occurred > 0) { sigwakeup_occurred--; Signal = SIGWAKEUP; sprintf(message_buffer, "Received wakeup signal"); report_message(MSG_TRACE); } else { Signal = 0; // unexpected event sprintf(message_buffer, "Received unexpected signal"); report_message(MSG_WARNING); } return (Signal); } #endif #ifdef LINK int wait_for_wakeup () { sigset_t newsignalSet; sigset_t oldsignalSet; report_message(MSG_TRACE); if (signal_occurred == 0) { sigemptyset(&newsignalSet); sigaddset(&newsignalSet,SIGWAKEUP); sigaddset(&newsignalSet,SIGUSR1); sigaddset(&newsignalSet,SIGUSR2); sigprocmask(SIG_BLOCK,&newsignalSet,&oldsignalSet); } if (signal_occurred == 0) { sigdelset(&oldsignalSet,SIGWAKEUP); sigdelset(&oldsignalSet,SIGUSR1); sigdelset(&oldsignalSet,SIGUSR2); (void) sigsuspend(&oldsignalSet); } sprintf(message_buffer, "wakeup occurred: %d, %d, %d, %d", signal_occurred, sigusr1_occurred, sigusr2_occurred, sigwakeup_occurred); report_message(MSG_TRACE); signal_occurred--; if (sigusr1_occurred > 0) { sigusr1_occurred--; Signal = SIGUSR1; sprintf(message_buffer, "Received USR1 signal"); report_message(MSG_TRACE); } else if (sigusr2_occurred > 0) { sigusr2_occurred--; Signal = SIGUSR2; sprintf(message_buffer, "Received USR2 signal"); report_message(MSG_TRACE); } else if (sigwakeup_occurred > 0) { sigwakeup_occurred--; Signal = SIGWAKEUP; sprintf(message_buffer, "Received wakeup signal"); report_message(MSG_TRACE); } else { Signal = 0; // unexpected event sprintf(message_buffer, "Received unexpected signal"); report_message(MSG_WARNING); } return (Signal); } #endif