- Updated all Logged messages, standardised DebugLevel:
- dlNone - Show startup and stop
- dlLow - Show creation/destruction of Function Blocks and Local IO
- dlMedium - Show connection events, eg. open/close
- dlHigh - Show data flow events
-LogCore:
- LogMessage and ShowOutput uses va_list
only run printf if DebugLevel correct
- Remove global LogStr[] variable
- SelectableCore:
- Implemented Auto-management of handles
auto open on startup/fail/close
- Changed simple Open/Close/Read/Write methods to inline
- Do not set Select Write trigger for server socket
- Memory leak, setting address twice on RemoteClient
- Bug fix, only send handle out data if DebugLevel = dlHigh
- Bug fix, do not Read/ProcessBuffer if no InputBuffer
134 lines
3.9 KiB
C++
134 lines
3.9 KiB
C++
/*
|
|
* SignalCore.cpp
|
|
*
|
|
* Created on: 17 May 2016
|
|
* Author: wentzelc
|
|
*/
|
|
|
|
// redA Libraries
|
|
#include "SignalCore.h"
|
|
#include "LogCore.h"
|
|
|
|
// Standard C/C++ Libraries
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <iostream>
|
|
#include <string.h>
|
|
|
|
#include <signal.h>
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
// 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 );
|
|
|
|
// 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( SIGPIPE, &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 );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|