/* * SignalCore.cpp * * Created on: 17 May 2016 * Author: wentzelc */ // Standard C/C++ Libraries #include #include // redA Libraries #include "ApplicationCore.h" #include "SignalCore.h" //--------------------------------------------------------------------------- // Global vars extern char * ProcessName; extern CApplication * Application; // Termination Vars bool Terminate = false; int TermCount = 0; int MaxTermCount = 5; //--------------------------------------------------------------------------- // Configure Signal handling void ConfigureSignalHandlers() { struct sigaction TermAct; struct sigaction AbortAct; // Signals to be ignored signal( SIGCHLD, SIG_IGN ); signal( SIGPIPE, SIG_IGN ); // Signals for normal termination TermAct.sa_handler = SignalTerminate; sigemptyset( &TermAct.sa_mask ); TermAct.sa_flags = SA_RESTART; sigaction( SIGHUP, &TermAct, 0 ); sigaction( SIGINT, &TermAct, 0 ); sigaction( SIGQUIT, &TermAct, 0 ); sigaction( SIGTERM, &TermAct, 0 ); sigaction( SIGTSTP, &TermAct, 0 ); // Signals for immediate termination AbortAct.sa_handler = SignalAbort; sigemptyset( &AbortAct.sa_mask ); AbortAct.sa_flags = 0; sigaction( SIGABRT, &AbortAct, 0 ); sigaction( SIGFPE, &AbortAct, 0 ); sigaction( SIGILL, &AbortAct, 0 ); sigaction( SIGSEGV, &AbortAct, 0 ); } //--------------------------------------------------------------------------- // Signal handler to terminate program the standard way void SignalTerminate( int sig ) { char SigName[10]; // Determine signal name switch (sig) { case SIGHUP : strcpy( SigName, "SIGHUP " ); break; case SIGINT : strcpy( SigName, "SIGINT " ); break; case SIGQUIT : strcpy( SigName, "SIGQUIT" ); break; case SIGTERM : strcpy( SigName, "SIGTERM" ); break; case SIGTSTP : strcpy( SigName, "SIGTSTP" ); break; default : strcpy( SigName, "UNKNOWN" ); break; } // Allow process to terminate normally Terminate = true; TermCount++; std::cerr << std::endl << ProcessName << ": ***********************************" << std::endl; // Create Application->Log Entry if (Application->Log) { Application->Log->Message( dlLow, dlLow, "%s: ** %s signal received [%d] **", ProcessName, SigName, TermCount ); // Check for Terminate Limit if (TermCount < MaxTermCount) { Application->Log->Message( dlLow, dlLow, "%s: ** Terminating normally... **", ProcessName ); } else { Application->Log->Message( dlLow, dlLow, "%s: ** Terminating immediately! **", ProcessName ); } } else { std::cerr << ProcessName << ": ** " << SigName << " signal received [" << TermCount << "] **" << std::endl; // Check for Terminate Limit if (TermCount < MaxTermCount) { std::cerr << ProcessName << ": ** Terminating normally... **" << std::endl; } else { std::cerr << ProcessName << ": ** Terminating immediately! **" << std::endl; } } std::cerr << ProcessName << ": ***********************************" << std::endl << std::endl; // Check for Terminate Limit if (TermCount >= MaxTermCount) { exit( sig ); } return; }//--------------------------------------------------------------------------- // Signal Handler to terminate program immediately void SignalAbort( int sig ) { char SigName[10]; // Determine Signal name switch (sig) { case SIGABRT : strcpy( SigName, "SIGABRT" ); break; case SIGFPE : strcpy( SigName, "SIGFPE " ); break; case SIGILL : strcpy( SigName, "SIGILL " ); break; case SIGPIPE : strcpy( SigName, "SIGPIPE" ); break; case SIGSEGV : strcpy( SigName, "SIGSEGV" ); break; default : strcpy( SigName, "UNKNOWN" ); break; } // Show signal received std::cerr << std::endl << ProcessName << ": ********************************" << std::endl; // Create Application->Log Entry - but don't post if (Application->Log) { Application->Log->Message( dlLow, dlLow, "%s: ** %s signal received **", ProcessName, SigName ); Application->Log->Message( dlLow, dlLow, "%s: ** Terminating immediately! **", ProcessName ); } else { std::cerr << ProcessName << ": ** " << SigName << " signal received **" << std::endl; std::cerr << ProcessName << ": ** Terminating immediately! **" << std::endl; } std::cerr << ProcessName << ": ********************************" << std::endl << std::endl; // Terminate with signal exit( sig ); } //---------------------------------------------------------------------------