/* * SignalCore.cpp * * Created on: 17 May 2016 * Author: wentzelc */ // redA Libraries #include "SignalCore.h" #include "LogCore.h" // Standard C/C++ Libraries #include #include #include #include #include //--------------------------------------------------------------------------- // Global vars extern char ProcessName[]; // 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++; // Check for Terminate Limit // Show signal received if not already terminated std::cerr << "\r\n" << ProcessName << ": ***********************************\n"; // Create Log Entry LogMessage( dlNone, "%s: ** %s signal received [%d] **", ProcessName, SigName, TermCount ); if (TermCount < MaxTermCount) LogMessage( dlNone, "%s: ** Terminating normally... **", ProcessName ); else LogMessage( dlNone, "%s: ** Terminating immediately! **", ProcessName ); std::cerr << ProcessName << ": ***********************************\n\n"; 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 << "\n" << ProcessName << ": ********************************\n"; // Create Log Entry - but don't post LogMessage( dlNone, "%s: ** %s signal received **", ProcessName, SigName ); LogMessage( dlNone, "%s: ** Terminating immediately! **", ProcessName ); std::cerr << ProcessName << ": ********************************\n\n"; // Terminate with signal exit( sig ); } //---------------------------------------------------------------------------