Major update:
- Logging
- Created LogCore Class
- Updated LogCore to use file descriptors instead of stdout
- Add Log object reference to constructors for:
FunctionCore, SelectCore
- Use extern Log() object in SignalCore
- SelectableCore
- Added new connection type: ForkedPipe
Create pipe, fork process, connect pipe out to child stdin, exec
This commit is contained in:
18
FileCore.cpp
18
FileCore.cpp
@@ -27,8 +27,8 @@ const float PI = 3.1415927;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CFileCore::CFileCore( const char * Name, EDebugLevel pDebugLevel, int pOuputDisplay ) :
|
||||
CFunctionCore( Name, pDebugLevel, pOuputDisplay )
|
||||
CFileCore::CFileCore( const char * Name, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay ) :
|
||||
CFunctionCore( Name, pLog, pDebugLevel, pOuputDisplay )
|
||||
{
|
||||
FirstFile = NULL;
|
||||
|
||||
@@ -143,7 +143,7 @@ bool CFileCore::OpenFile( TFileHandle * FileHandle )
|
||||
// temp
|
||||
//char FilePath[50];
|
||||
//sprintf( FilePath, "%s%03d", FileHandle->Path, x++ );
|
||||
//LogMessage( DebugLevel, dlNone, "f: %s", FilePath );
|
||||
//if (Log) Log->Message( DebugLevel, dlNone, "f: %s", FilePath );
|
||||
// temp
|
||||
|
||||
// GEt file handle
|
||||
@@ -160,7 +160,7 @@ bool CFileCore::OpenFile( TFileHandle * FileHandle )
|
||||
// temp
|
||||
|
||||
// Report result
|
||||
LogMessage( DebugLevel, dlHigh, "%s: File '%s' - Opened", Name, FileHandle->Name );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "%s: File '%s' - Opened", Name, FileHandle->Name );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ bool CFileCore::OpenFile( TFileHandle * FileHandle )
|
||||
if (!isOpen(FileHandle))
|
||||
{
|
||||
// Report result
|
||||
LogMessage( DebugLevel, dlHigh, "%s: File '%s' - Could not open (%d) %s", Name, FileHandle->Name, errno, strerror(errno) );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "%s: File '%s' - Could not open (%d) %s", Name, FileHandle->Name, errno, strerror(errno) );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -192,13 +192,13 @@ bool CFileCore::CloseFile( TFileHandle * FileHandle )
|
||||
|
||||
// Report result
|
||||
if (!isOpen(FileHandle)) {
|
||||
LogMessage( DebugLevel, dlHigh, "%s: File '%s' - Closed", Name, FileHandle->Name );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "%s: File '%s' - Closed", Name, FileHandle->Name );
|
||||
} else {
|
||||
LogMessage( DebugLevel, dlHigh, "%s: File '%s' - Could not close", Name, FileHandle->Name );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "%s: File '%s' - Could not close", Name, FileHandle->Name );
|
||||
}
|
||||
|
||||
// temp
|
||||
LogMessage( DebugLevel, dlNone, "%s: File '%s' - Bytes written %d (%d)", Name, FileHandle->Name, count, (count-5038848) );
|
||||
if (Log) Log->Message( DebugLevel, dlNone, "%s: File '%s' - Bytes written %d (%d)", Name, FileHandle->Name, count, (count-5038848) );
|
||||
// temp
|
||||
|
||||
}
|
||||
@@ -282,7 +282,7 @@ int CFileCore::Input( const char * IOName, const char * Data, int MaxLen )
|
||||
if (!(FileHandle = GetFile( IOName )))
|
||||
{
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlHigh, "%s: Local IO '%s' - Input rejected, Local IO not found", Name, IOName );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "%s: Local IO '%s' - Input rejected, Local IO not found", Name, IOName );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ private:
|
||||
|
||||
public:
|
||||
// Life cycle
|
||||
CFileCore( const char * Name, EDebugLevel pDebugLevel, int pOuputDisplay );
|
||||
CFileCore( const char * Name, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay );
|
||||
~CFileCore();
|
||||
|
||||
// Manage files
|
||||
|
||||
@@ -22,7 +22,7 @@ extern char ProcessName[];
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Life cycle
|
||||
CFunctionCore::CFunctionCore( const char * FunctionName, EDebugLevel pDebugLevel, int pOuputDisplay )
|
||||
CFunctionCore::CFunctionCore( const char * FunctionName, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay )
|
||||
{
|
||||
// Set name
|
||||
if (FunctionName) {
|
||||
@@ -37,11 +37,12 @@ CFunctionCore::CFunctionCore( const char * FunctionName, EDebugLevel pDebugLevel
|
||||
FirstIO = NULL;
|
||||
|
||||
// Output
|
||||
Log = pLog;
|
||||
OutputDisplay = pOuputDisplay;
|
||||
DebugLevel = pDebugLevel;
|
||||
|
||||
// Report status
|
||||
LogMessage( DebugLevel, dlLow, "%s: Function '%s' - Created", ProcessName, FunctionName );
|
||||
if (Log) Log->Message( DebugLevel, dlLow, "%s: Function '%s' - Created", ProcessName, FunctionName );
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -86,7 +87,7 @@ CFunctionCore::~CFunctionCore()
|
||||
}
|
||||
|
||||
// Report status
|
||||
LogMessage( DebugLevel, dlLow, "%s: Function '%s' - Destroyed", ProcessName, Name );
|
||||
if (Log) Log->Message( DebugLevel, dlLow, "%s: Function '%s' - Destroyed", ProcessName, Name );
|
||||
|
||||
// Destroy Name
|
||||
if (Name) {
|
||||
@@ -122,7 +123,7 @@ TLocalIO * CFunctionCore::AddLocalIO( const char * IOName )
|
||||
strcpy( (*LocalIO)->Name, IOName );
|
||||
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlLow, "%s: Local IO '%s' - Created", Name, IOName );
|
||||
if (Log) Log->Message( DebugLevel, dlLow, "%s: Local IO '%s' - Created", Name, IOName );
|
||||
}
|
||||
|
||||
return *LocalIO;
|
||||
@@ -159,7 +160,7 @@ bool CFunctionCore::AddInput( const char * IOName, CFunctionCore * OutFunction,
|
||||
strcpy( (*LinkedIO)->IOName, OutputName );
|
||||
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlLow, "%s: Input Linked - '%s'/'%s' <-- '%s'/'%s'", Name, Name, IOName, OutFunction->GetName(), OutputName );
|
||||
if (Log) Log->Message( DebugLevel, dlLow, "%s: Input Linked - '%s'/'%s' <-- '%s'/'%s'", Name, Name, IOName, OutFunction->GetName(), OutputName );
|
||||
}
|
||||
|
||||
// Link Return direction as well
|
||||
@@ -200,7 +201,7 @@ bool CFunctionCore::AddOutput( const char * IOName, CFunctionCore * InFunction,
|
||||
strcpy( (*LinkedIO)->IOName, InputName );
|
||||
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlLow, "%s: Output Linked - '%s'/'%s' --> '%s'/'%s'", Name, Name, IOName, InFunction->GetName(), InputName );
|
||||
if (Log) Log->Message( DebugLevel, dlLow, "%s: Output Linked - '%s'/'%s' --> '%s'/'%s'", Name, Name, IOName, InFunction->GetName(), InputName );
|
||||
}
|
||||
|
||||
// Link return direction as well
|
||||
@@ -229,12 +230,12 @@ int CFunctionCore::Input( const char * IOName, const char * Data, int MaxLen )
|
||||
if (!(LocalIO = GetLocalIO( IOName )))
|
||||
{
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlHigh, "%s: Local IO '%s' - Input rejected, Local IO not found", Name, IOName );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "%s: Local IO '%s' - Input rejected, Local IO not found", Name, IOName );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Log event
|
||||
ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, MaxLen, "%s: Local IO '%s' - IN:", Name, IOName );
|
||||
if (Log) Log->Output( DebugLevel, dlHigh, OutputDisplay, Data, MaxLen, "%s: Local IO '%s' - IN:", Name, IOName );
|
||||
|
||||
// Return processed bytes
|
||||
return MaxLen;
|
||||
@@ -256,7 +257,7 @@ int CFunctionCore::Output( const char * IOName, const char * Data, int Len )
|
||||
if (!(LocalIO = GetLocalIO( IOName )))
|
||||
{
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlHigh, "%s: Local IO '%s' - Output rejected, Local IO not found", Name, IOName );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "%s: Local IO '%s' - Output rejected, Local IO not found", Name, IOName );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -277,7 +278,7 @@ int CFunctionCore::Output( const TLocalIO * LocalIO, const char * Data, int Len
|
||||
}
|
||||
|
||||
// Log event
|
||||
ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Local IO '%s' - OUT:", Name, LocalIO->Name );
|
||||
if (Log) Log->Output( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Local IO '%s' - OUT:", Name, LocalIO->Name );
|
||||
|
||||
// Pass output to all linked inputs
|
||||
Output = LocalIO->FirstOutput;
|
||||
|
||||
@@ -56,6 +56,7 @@ protected:
|
||||
TLocalIO * FirstIO;
|
||||
|
||||
// Output
|
||||
CLogCore * Log;
|
||||
EDebugLevel DebugLevel;
|
||||
int OutputDisplay;
|
||||
|
||||
@@ -73,7 +74,7 @@ protected:
|
||||
|
||||
public:
|
||||
// Life cycle
|
||||
CFunctionCore( const char * ObjectName, EDebugLevel pDebugLevel, int pOuputDisplay );
|
||||
CFunctionCore( const char * ObjectName, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay );
|
||||
virtual ~CFunctionCore();
|
||||
|
||||
// Miscellaneous
|
||||
|
||||
42
LogCore.cpp
42
LogCore.cpp
@@ -22,7 +22,13 @@ char LogStr[1000]; // Temporary var to create log messages,
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool LogMessage( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const char * Format, ... )
|
||||
CLogCore::CLogCore( FILE * pFileOutput )
|
||||
{
|
||||
FileOutput = pFileOutput;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CLogCore::Message( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const char * Format, ... )
|
||||
{
|
||||
va_list ArgPtr;
|
||||
|
||||
@@ -31,20 +37,20 @@ bool LogMessage( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const char * Form
|
||||
return false;
|
||||
|
||||
// Check debug level
|
||||
if (MsgLevel > DebugLevel) {
|
||||
if (!FileOutput || (MsgLevel > DebugLevel)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Show normal output
|
||||
va_start( ArgPtr, Format );
|
||||
vprintf( Format, ArgPtr );
|
||||
printf( "\r\n" );
|
||||
vfprintf( FileOutput, Format, ArgPtr );
|
||||
fprintf( FileOutput, "\r\n" );
|
||||
va_end( ArgPtr );
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool ShowOutput( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show, const char * Buffer, int Len, const char * Format, ... )
|
||||
bool CLogCore::Output( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show, const char * Buffer, int Len, const char * Format, ... )
|
||||
{
|
||||
va_list ArgPtr;
|
||||
|
||||
@@ -53,7 +59,7 @@ bool ShowOutput( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show,
|
||||
return false;
|
||||
|
||||
// Check debug level
|
||||
if (MsgLevel > DebugLevel) {
|
||||
if (!FileOutput || (MsgLevel > DebugLevel)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -64,7 +70,7 @@ bool ShowOutput( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show,
|
||||
// Show Lead
|
||||
if (Format && *Format) {
|
||||
va_start( ArgPtr, Format );
|
||||
vprintf( Format, ArgPtr );
|
||||
vfprintf( FileOutput, Format, ArgPtr );
|
||||
va_end( ArgPtr );
|
||||
}
|
||||
|
||||
@@ -72,11 +78,11 @@ bool ShowOutput( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show,
|
||||
if (Show & OUT_COUNT)
|
||||
{
|
||||
// Print byte count
|
||||
printf( " [%d] ", Len );
|
||||
fprintf( FileOutput, " [%d] ", Len );
|
||||
|
||||
// EOL if only count wanted
|
||||
if (Show & OUT_COUNT) {
|
||||
printf( "\n" );
|
||||
fprintf( FileOutput, "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,25 +91,25 @@ bool ShowOutput( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show,
|
||||
{
|
||||
if (Show & OUT_ASIS) {
|
||||
// Print entire buffer as is (line feeds included)
|
||||
printf( "%s", Buffer );
|
||||
fprintf( FileOutput, "%s", Buffer );
|
||||
}
|
||||
else {
|
||||
// Ignore \r\n
|
||||
for (int i=0; i<Len; i++) {
|
||||
if ((Buffer[i] < 32) || (Buffer[i] > 126)) {
|
||||
if ((Show & OUT_CRLF) && ((Buffer[i] == '\r') || (Buffer[i] == '\n')))
|
||||
printf( "%c", Buffer[i] );
|
||||
fprintf( FileOutput, "%c", Buffer[i] );
|
||||
else
|
||||
printf( "." );
|
||||
fprintf( FileOutput, "." );
|
||||
}
|
||||
else {
|
||||
printf( "%c", Buffer[i] );
|
||||
fprintf( FileOutput, "%c", Buffer[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add EOL if not present or ignored
|
||||
if (!(Show & (OUT_ASIS | OUT_CRLF)) || (Buffer[Len-1] != '\n')) {
|
||||
printf( "\n" );
|
||||
fprintf( FileOutput, "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,9 +118,9 @@ bool ShowOutput( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show,
|
||||
{
|
||||
// Print Hex values of individual bytes
|
||||
for (int i=0; i<Len; i++) {
|
||||
printf( "%02X ", (unsigned char)Buffer[i] );
|
||||
fprintf( FileOutput, "%02X ", (unsigned char)Buffer[i] );
|
||||
}
|
||||
printf( "\n" );
|
||||
fprintf( FileOutput, "\n" );
|
||||
}
|
||||
|
||||
// Show Binary output
|
||||
@@ -122,10 +128,10 @@ bool ShowOutput( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show,
|
||||
// Print each byte as 8-bit binary
|
||||
for (int i=0; i<Len; i++) {
|
||||
for (int j=0; j<8; j++) {
|
||||
printf( "%d", (bool)((Buffer[i] << j) & 0x80) );
|
||||
fprintf( FileOutput, "%d", (bool)((Buffer[i] << j) & 0x80) );
|
||||
}
|
||||
}
|
||||
printf( "\n" );
|
||||
fprintf( FileOutput, "\n" );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
13
LogCore.h
13
LogCore.h
@@ -12,7 +12,7 @@
|
||||
/* none */
|
||||
|
||||
// Standard C/C++ Libraries
|
||||
/* none */
|
||||
#include <stdio.h>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -31,10 +31,17 @@ typedef enum { dlNone = 0, dlLow = 1, dlMedium = 2, dlHigh = 3 } EDebugLevel;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool LogMessage( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const char * Format, ... );
|
||||
class CLogCore
|
||||
{
|
||||
private:
|
||||
FILE * FileOutput;
|
||||
|
||||
bool ShowOutput( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show, const char * Buffer, int Len, const char * Format, ... );
|
||||
public:
|
||||
CLogCore( FILE * pFileOutput );
|
||||
|
||||
bool Message( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const char * Format, ... );
|
||||
bool Output( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show, const char * Buffer, int Len, const char * Format, ... );
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#endif /* REDACORE_OGCORE_H_ */
|
||||
|
||||
@@ -23,7 +23,7 @@ extern char ProcessName[];
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Create Select
|
||||
CSelect::CSelect( long SelectTimeout, EDebugLevel pDebugLevel )
|
||||
CSelect::CSelect( long SelectTimeout, CLogCore * pLog, EDebugLevel pDebugLevel )
|
||||
{
|
||||
// Clear List
|
||||
FirstHandle = NULL;
|
||||
@@ -39,10 +39,11 @@ CSelect::CSelect( long SelectTimeout, EDebugLevel pDebugLevel )
|
||||
SetInterval( &Timeout, SelectTimeout );
|
||||
|
||||
// Output
|
||||
Log = pLog;
|
||||
DebugLevel = pDebugLevel;
|
||||
|
||||
// Show status
|
||||
LogMessage( DebugLevel, dlLow, "%s: Select - Created", ProcessName );
|
||||
if (Log) Log->Message( DebugLevel, dlLow, "%s: Select - Created", ProcessName );
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -60,7 +61,7 @@ CSelect::~CSelect()
|
||||
}
|
||||
|
||||
// Show status
|
||||
LogMessage( DebugLevel, dlLow, "%s: Select - Destroyed", ProcessName );
|
||||
if (Log) Log->Message( DebugLevel, dlLow, "%s: Select - Destroyed", ProcessName );
|
||||
return;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -105,7 +106,7 @@ void CSelect::Add( int FD, bool Read, bool Write, CSelectableCore * Function )
|
||||
FD_SET( FD, &ReadTestFDS );
|
||||
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlHigh, "Select: FD [%d] - Add Read", FD );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "Select: FD [%d] - Add Read", FD );
|
||||
}
|
||||
|
||||
// Add Write Select
|
||||
@@ -114,7 +115,7 @@ void CSelect::Add( int FD, bool Read, bool Write, CSelectableCore * Function )
|
||||
FD_SET( FD, &WriteTestFDS );
|
||||
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlHigh, "Select: FD [%d] - Add Write", FD );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "Select: FD [%d] - Add Write", FD );
|
||||
}
|
||||
|
||||
// Check Maximum File Handle
|
||||
@@ -142,7 +143,7 @@ void CSelect::Remove( int FD, bool Read, bool Write )
|
||||
FD_CLR( FD, &ReadTestFDS);
|
||||
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlHigh, "Select: FD [%d] - Remove Read", FD );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "Select: FD [%d] - Remove Read", FD );
|
||||
}
|
||||
|
||||
// Remove from set for select write check
|
||||
@@ -151,7 +152,7 @@ void CSelect::Remove( int FD, bool Read, bool Write )
|
||||
FD_CLR( FD, &WriteTestFDS);
|
||||
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlHigh, "Select: FD [%d] - Remove Write", FD );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "Select: FD [%d] - Remove Write", FD );
|
||||
}
|
||||
// Handle will be removed in Test() if both Read & Write flags are false
|
||||
}
|
||||
@@ -173,7 +174,7 @@ bool CSelect::Test()
|
||||
Events = select( MaxFD, &ReadFDS, &WriteFDS, (fd_set*)NULL, &STimeout );
|
||||
if (Events < 0)
|
||||
{
|
||||
LogMessage( DebugLevel, dlHigh, "Select: Select operation failed" );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "Select: Select operation failed" );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CSelectableCore::CSelectableCore( const char * Name, CSelect * Selector, EDebugLevel pDebugLevel, int pOutputDisplay ) :
|
||||
CFunctionCore( Name, pDebugLevel, pOutputDisplay )
|
||||
CSelectableCore::CSelectableCore( const char * Name, CSelect * Selector, CLogCore * pLog, EDebugLevel pDebugLevel, int pOutputDisplay ) :
|
||||
CFunctionCore( Name, pLog, pDebugLevel, pOutputDisplay )
|
||||
{
|
||||
// Handles
|
||||
FirstHandle = NULL;
|
||||
@@ -85,7 +85,7 @@ THandle * CSelectableCore::CreateHandle( const char * HandleName, bool CreateLo
|
||||
(*Handle)->FD = -1;
|
||||
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Created", Name, HandleName );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Created", Name, HandleName );
|
||||
}
|
||||
|
||||
// Create Matching IO point
|
||||
@@ -117,7 +117,7 @@ bool CSelectableCore::RemoveHandle( THandle * Handle )
|
||||
}
|
||||
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Removed", Name, Handle->Name );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Removed", Name, Handle->Name );
|
||||
|
||||
// Destroy Child handle
|
||||
DestroyHandle( Handle );
|
||||
@@ -134,8 +134,8 @@ bool CSelectableCore::DestroyHandle( THandle * Handle )
|
||||
// Clear parameters
|
||||
if (Handle->Name)
|
||||
free( Handle->Name );
|
||||
if (Handle->FileName)
|
||||
free( Handle->FileName );
|
||||
if (Handle->Path)
|
||||
free( Handle->Path );
|
||||
if (Handle->Address)
|
||||
free( Handle->Address );
|
||||
|
||||
@@ -166,16 +166,41 @@ bool CSelectableCore::SetPortHandle( THandle * Handle, const char * FileName )
|
||||
Handle->Type = ctPort;
|
||||
|
||||
// Clear File Name
|
||||
if (Handle->FileName) {
|
||||
free( Handle->FileName );
|
||||
if (Handle->Path) {
|
||||
free( Handle->Path );
|
||||
}
|
||||
|
||||
// Set name
|
||||
Handle->FileName = (char*)malloc( strlen(FileName)+1 );
|
||||
strcpy( Handle->FileName, FileName );
|
||||
Handle->Path = (char*)malloc( strlen(FileName)+1 );
|
||||
strcpy( Handle->Path, FileName );
|
||||
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Set as Port [%s]", Name, Handle->Name, FileName );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Set as Port [%s]", Name, Handle->Name, FileName );
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CSelectableCore::SetForkPipeHandle( THandle * Handle, const char * ExecPath )
|
||||
{
|
||||
// Validate
|
||||
if (!Handle || (Handle->Type != ctNone) || !ExecPath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set Type
|
||||
Handle->Type = ctForkPipe;
|
||||
|
||||
// Clear File Name
|
||||
if (Handle->Path) {
|
||||
free( Handle->Path );
|
||||
}
|
||||
|
||||
// Set name
|
||||
Handle->Path = (char*)malloc( strlen(ExecPath)+1 );
|
||||
strcpy( Handle->Path, ExecPath );
|
||||
|
||||
// Log event
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Set as ForkPipe [%s]", Name, Handle->Name, ExecPath );
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -202,7 +227,7 @@ bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, con
|
||||
Handle->PortNo = PortNo;
|
||||
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Set as %s [%s:%d]", Name, Handle->Name, ConnectTypeName[Type], Address, PortNo );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Set as %s [%s:%d]", Name, Handle->Name, ConnectTypeName[Type], Address, PortNo );
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -215,9 +240,9 @@ bool CSelectableCore::ClearHandle( THandle * Handle )
|
||||
}
|
||||
|
||||
// Reset Type related parameters
|
||||
if (Handle->FileName) {
|
||||
free( Handle->FileName );
|
||||
Handle->FileName = NULL;
|
||||
if (Handle->Path) {
|
||||
free( Handle->Path );
|
||||
Handle->Path = NULL;
|
||||
}
|
||||
if (Handle->Address) {
|
||||
free( Handle->Address );
|
||||
@@ -229,7 +254,7 @@ bool CSelectableCore::ClearHandle( THandle * Handle )
|
||||
Handle->Type = ctNone;
|
||||
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Set as None", Name, Handle->Name );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Set as None", Name, Handle->Name );
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -298,24 +323,24 @@ int CSelectableCore::OpenPort( THandle * Handle )
|
||||
}
|
||||
|
||||
// Check if port exits
|
||||
if (access( Handle->FileName, F_OK ) != 0)
|
||||
if (access( Handle->Path, F_OK ) != 0)
|
||||
{
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Port not found [%s]", Name, Handle->Name, Handle->FileName );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Port not found [%s]", Name, Handle->Name, Handle->Path );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Open Port
|
||||
Handle->FD = open( Handle->FileName, O_RDWR );
|
||||
Handle->FD = open( Handle->Path, O_RDWR );
|
||||
if (Handle->FD == -1)
|
||||
{
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Could not open Port [%s]", Name, Handle->Name, Handle->FileName );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Could not open Port [%s]", Name, Handle->Name, Handle->Path );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Port opened [%s]", Name, Handle->Name, Handle->FileName );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Port opened [%s]", Name, Handle->Name, Handle->Path );
|
||||
|
||||
// Add to Select Lists
|
||||
if (Select) {
|
||||
@@ -329,6 +354,102 @@ int CSelectableCore::OpenPort( THandle * Handle )
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
int CSelectableCore::OpenForkPipe( THandle * Handle )
|
||||
{
|
||||
int pipefd[2];
|
||||
char * Args[50];
|
||||
int Count = 0;
|
||||
|
||||
// Validate
|
||||
if (!Handle || (Handle->Type == ctNone)) {
|
||||
return -1;
|
||||
} else if (Handle->State == csOpen) {
|
||||
return Handle->FD;
|
||||
}
|
||||
|
||||
// Validate Exec path
|
||||
if (!Handle->Path || !*(Handle->Path))
|
||||
{
|
||||
// Log event
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Invalid path for Exec", Name, Handle->Name );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create Pipe
|
||||
pipe( pipefd );
|
||||
if ((pipefd[0] == -1) || (pipefd[1] == -1))
|
||||
{
|
||||
// Log event
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Could not open Pipe", Name, Handle->Name );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Fork process
|
||||
Handle->ChildPID = fork();
|
||||
if (Handle->ChildPID < 0)
|
||||
{
|
||||
// Fork has failed
|
||||
// Close both ends of the pipe
|
||||
close( pipefd[0] );
|
||||
close( pipefd[1] );
|
||||
Handle->FD = -1;
|
||||
|
||||
// Log event
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Could not Fork process", Name, Handle->Name );
|
||||
return -1;
|
||||
}
|
||||
else if (Handle->ChildPID > 0)
|
||||
{
|
||||
// Fork success - this is parent
|
||||
// Close Read-end of pipe, but keep the Write-end
|
||||
close( pipefd[0] );
|
||||
Handle->FD = pipefd[1];
|
||||
|
||||
write( Handle->FD, "testing\n", 8 );
|
||||
|
||||
// Log event
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Process forked successfully", Name, Handle->Name );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fork success - this is child
|
||||
printf( "child\n" );
|
||||
|
||||
// Replace stdin with Read-end of pipe
|
||||
close( 0 );
|
||||
dup( pipefd[0] );
|
||||
close( pipefd[0] );
|
||||
|
||||
// Close Write-end of pipe
|
||||
close( pipefd[1] );
|
||||
|
||||
// Replace Processing image
|
||||
BuildArgs( Handle->Path, Count, Args );
|
||||
// printf( "Execute params [%d]:\n", Count );
|
||||
// int i = 0;
|
||||
// while (Args[i]) {
|
||||
// printf( "%d: %s\n", i, Args[i] );
|
||||
// i++;
|
||||
// }
|
||||
execvp( Args[0], Args );
|
||||
|
||||
// Replace failed, exit immediately
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Exec on forked process failed", Name, Handle->Name );
|
||||
exit(127);
|
||||
}
|
||||
|
||||
// Add to Select Lists
|
||||
if (Select) {
|
||||
Select->Add( Handle->FD, false, true, this );
|
||||
}
|
||||
|
||||
// Set state
|
||||
Handle->State = csOpen;
|
||||
return Handle->FD;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
int CSelectableCore::OpenServerSocket( THandle * Handle )
|
||||
{
|
||||
socklen_t addr_len;
|
||||
@@ -360,7 +481,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
|
||||
if ((Handle->FD = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Failed to create Server socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Failed to create Server socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
|
||||
// Set state
|
||||
Handle->State = csFailed;
|
||||
@@ -372,7 +493,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
|
||||
(setsockopt( Handle->FD, SOL_SOCKET, SO_REUSEADDR, &Reuse_opt, sizeof(Reuse_opt)) == -1))
|
||||
{
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Could not set socket options [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Could not set socket options [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
|
||||
// Set state
|
||||
Handle->State = csFailed;
|
||||
@@ -387,7 +508,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
|
||||
(setsockopt( Handle->FD, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ))
|
||||
{
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Could not set KeepAlive options [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Could not set KeepAlive options [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
|
||||
// Set state
|
||||
Handle->State = csFailed;
|
||||
@@ -402,7 +523,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
|
||||
if (bind( Handle->FD, (struct sockaddr *)&address, addr_len ) < 0)
|
||||
{
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Failed to bind Server socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Failed to bind Server socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
|
||||
// Set state
|
||||
close( Handle->FD );
|
||||
@@ -415,7 +536,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
|
||||
if (listen( Handle->FD, 5 ) < 0)
|
||||
{
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Failed to listen on Server socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Failed to listen on Server socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
|
||||
// Set state
|
||||
close( Handle->FD );
|
||||
@@ -425,7 +546,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
|
||||
};
|
||||
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Server binded and listening [%s:%d]", Name, Handle->Name, Handle->Address, Handle->PortNo );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Server binded and listening [%s:%d]", Name, Handle->Name, Handle->Address, Handle->PortNo );
|
||||
|
||||
// Add to Select Lists
|
||||
if (Select) {
|
||||
@@ -461,10 +582,12 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
|
||||
if ((ClientFD = accept( Handle->FD, (struct sockaddr *)&address, &addr_len)) == -1)
|
||||
{
|
||||
// Log Event
|
||||
if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Server failed to accept blocking connection (%s)", Name, Handle->Name, strerror(errno) );
|
||||
else
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Server failed to accept connection (%s)", Name, Handle->Name, strerror(errno) );
|
||||
if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Server failed to accept blocking connection (%s)", Name, Handle->Name, strerror(errno) );
|
||||
}
|
||||
else {
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Server failed to accept connection (%s)", Name, Handle->Name, strerror(errno) );
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -497,7 +620,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
|
||||
(*RemoteClient)->State = csWaitingtoOpen;
|
||||
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Server accepted Remote Client connection [%s]", Name, Handle->Name, ClientAddress );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Server accepted Remote Client connection [%s]", Name, Handle->Name, ClientAddress );
|
||||
|
||||
// Add to Select Lists
|
||||
if (Select) {
|
||||
@@ -517,7 +640,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
|
||||
else if (Handle->State == csWaitingtoOpen)
|
||||
{
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Remote Client connection open [%s]", Name, Handle->Name, Handle->Address );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Remote Client connection open [%s]", Name, Handle->Name, Handle->Address );
|
||||
|
||||
// Update state
|
||||
Handle->State = csOpen;
|
||||
@@ -551,7 +674,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
|
||||
if ((Handle->FD = socket( AF_INET, SOCK_STREAM, 0 )) < 0)
|
||||
{
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Failed to create Client socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Failed to create Client socket [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
|
||||
// Set Status
|
||||
Handle->State = csFailed;
|
||||
@@ -570,7 +693,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
|
||||
(setsockopt( Handle->FD, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ))
|
||||
{
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Could not set KeepAlive options [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Could not set KeepAlive options [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
|
||||
// Set State
|
||||
close( Handle->FD );
|
||||
@@ -588,7 +711,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
|
||||
|
||||
if (!connect( Handle->FD, (struct sockaddr *)&address, addr_len ))
|
||||
{
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Client connected [%s:%d]", Name, Handle->Name, Handle->Address, Handle->PortNo );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Client connected [%s:%d]", Name, Handle->Name, Handle->Address, Handle->PortNo );
|
||||
|
||||
// Add to Select Lists
|
||||
if (Select) {
|
||||
@@ -602,7 +725,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
|
||||
else if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EALREADY))
|
||||
{
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Client waiting to connect [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Client waiting to connect [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
|
||||
// Add to Select Lists
|
||||
if (Select) {
|
||||
@@ -616,7 +739,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
|
||||
else
|
||||
{
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Client could not connect [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Client could not connect [%s:%d] (%s)", Name, Handle->Name, Handle->Address, Handle->PortNo, strerror(errno) );
|
||||
|
||||
// Remove from Select List
|
||||
if (Select) {
|
||||
@@ -651,6 +774,9 @@ int CSelectableCore::Open( THandle * Handle )
|
||||
case ctPort :
|
||||
FD = OpenPort( Handle );
|
||||
break;
|
||||
case ctForkPipe :
|
||||
FD = OpenForkPipe( Handle );
|
||||
break;
|
||||
case ctServer :
|
||||
FD = OpenServerSocket( Handle );
|
||||
break;
|
||||
@@ -709,24 +835,29 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
|
||||
{
|
||||
case ctPort:
|
||||
// Log Event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Port %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->FileName );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Port %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Path );
|
||||
break;
|
||||
|
||||
case ctForkPipe:
|
||||
// Log Event
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Forked Pipe %s", Name, Handle->Name, ((Fail)? "failed" : "closed"));
|
||||
break;
|
||||
|
||||
case ctServer:
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Server %s [%s:%d]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Address, Handle->PortNo );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Server %s [%s:%d]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Address, Handle->PortNo );
|
||||
break;
|
||||
|
||||
case ctRemoteClient:
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Remote Client connection %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Address );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Remote Client connection %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Address );
|
||||
break;
|
||||
|
||||
case ctClient:
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Client connection %s [%s:%d]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Address, Handle->PortNo );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Client connection %s [%s:%d]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Address, Handle->PortNo );
|
||||
break;
|
||||
|
||||
case ctNone:
|
||||
default:
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - %s, invalid Handle type", Name, Handle->Name, ((Fail)? "failed" : "closed") );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - %s, invalid Handle type", Name, Handle->Name, ((Fail)? "failed" : "closed") );
|
||||
break;
|
||||
};
|
||||
|
||||
@@ -754,7 +885,7 @@ bool CSelectableCore::Read( THandle * Handle )
|
||||
}
|
||||
|
||||
// Log Read Event
|
||||
LogMessage( DebugLevel, dlHigh, "%s: Handle '%s' - Read Event", Name, Handle->Name );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "%s: Handle '%s' - Read Event", Name, Handle->Name );
|
||||
|
||||
// Check for closing/opening event on Socket
|
||||
if (Handle->Type == ctServer)
|
||||
@@ -830,7 +961,7 @@ bool CSelectableCore::Write( THandle * Handle )
|
||||
}
|
||||
|
||||
// Log Ready for Write Event
|
||||
LogMessage( DebugLevel, dlHigh, "%s: Handle '%s' - Write Event", Name, Handle->Name );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "%s: Handle '%s' - Write Event", Name, Handle->Name );
|
||||
|
||||
if (Handle->State == csWaitingtoOpen)
|
||||
{
|
||||
@@ -857,7 +988,7 @@ bool CSelectableCore::Write( THandle * Handle )
|
||||
if (DebugLevel >= dlHigh) {
|
||||
// Show event
|
||||
Len = Handle->OutBuffer->Peek( &Data );
|
||||
ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Handle '%s' - OUT:", Name, Handle->Name );
|
||||
if (Log) Log->Output( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Handle '%s' - OUT:", Name, Handle->Name );
|
||||
}
|
||||
|
||||
// Update Buffer
|
||||
@@ -902,7 +1033,7 @@ bool CSelectableCore::ProcessBuffer( THandle * Handle, bool Force )
|
||||
{
|
||||
// Show Packet
|
||||
Len = Handle->InBuffer->Peek( &Data );
|
||||
ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Handle '%s' - IN-F:", Name, Handle->Name );
|
||||
if (Log) Log->Output( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Handle '%s' - IN-F:", Name, Handle->Name );
|
||||
|
||||
// Write buffer to Outputs
|
||||
if (Handle->Type == ctRemoteClient) {
|
||||
@@ -921,7 +1052,7 @@ bool CSelectableCore::ProcessBuffer( THandle * Handle, bool Force )
|
||||
{
|
||||
// Show Packet
|
||||
Len = Handle->InBuffer->Peek( &Data, 0, Pos+1 );
|
||||
ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Handle '%s' - IN-M:", Name, Handle->Name );
|
||||
if (Log) Log->Output( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Handle '%s' - IN-M:", Name, Handle->Name );
|
||||
|
||||
// Write buffer to Outputs
|
||||
if (Handle->Type == ctRemoteClient) {
|
||||
@@ -1014,19 +1145,19 @@ int CSelectableCore::Input( const char * IOName, const char * Data, int Len )
|
||||
if (!(Handle = GetHandle( IOName )))
|
||||
{
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlHigh, "%s: Local IO '%s' - Input rejected, Input not found", Name, IOName );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "%s: Local IO '%s' - Input rejected, Input not found", Name, IOName );
|
||||
return 0;
|
||||
}
|
||||
// Check that handle is open
|
||||
else if (Handle->State != csOpen)
|
||||
{
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlHigh, "%s: Local IO '%s' - Input rejected, Handle not Open", Name, IOName );
|
||||
if (Log) Log->Message( DebugLevel, dlHigh, "%s: Local IO '%s' - Input rejected, Handle not Open", Name, IOName );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Log event
|
||||
ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Local IO '%s' - IN:", Name, IOName );
|
||||
if (Log) Log->Output( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Local IO '%s' - IN:", Name, IOName );
|
||||
|
||||
if (Handle->Type == ctServer)
|
||||
{
|
||||
@@ -1054,7 +1185,7 @@ int CSelectableCore::Input( const char * IOName, const char * Data, int Len )
|
||||
BytesWritten = WriteToFD( ChildHandle->FD, Data, Len, true );
|
||||
|
||||
// Show event
|
||||
ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Handle '%s' - OUT:", Name, ChildHandle->Name );
|
||||
if (Log) Log->Output( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Handle '%s' - OUT:", Name, ChildHandle->Name );
|
||||
}
|
||||
}
|
||||
// Next
|
||||
@@ -1080,7 +1211,7 @@ int CSelectableCore::Input( const char * IOName, const char * Data, int Len )
|
||||
else
|
||||
{
|
||||
// Show event
|
||||
ShowOutput( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Handle '%s' - OUT:", Name, Handle->Name );
|
||||
if (Log) Log->Output( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Handle '%s' - OUT:", Name, Handle->Name );
|
||||
|
||||
// Write directly to handle
|
||||
BytesWritten = WriteToFD( Handle->FD, Data, Len, true );
|
||||
@@ -1268,13 +1399,91 @@ bool CSelectableCore::SerialConfig( THandle * Handle, int Baud, short DataBits,
|
||||
if (tcsetattr( Handle->FD, TCSANOW, &newtio ) != 0)
|
||||
{
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Port not configured", Name, Handle->Name );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Port not configured", Name, Handle->Name );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Port configured
|
||||
// Log event
|
||||
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Port configured", Name, Handle->Name );
|
||||
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Port configured", Name, Handle->Name );
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CSelectableCore::BuildArgs( const char * ExecPath, int &Count, char * Args[] )
|
||||
{
|
||||
bool ParamStarted = false;
|
||||
bool OpenQuotes = false;
|
||||
char * MatchPos = NULL;
|
||||
char * StartPos = NULL;
|
||||
int Len;
|
||||
|
||||
// Validate
|
||||
if (!ExecPath || !*ExecPath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Split params
|
||||
MatchPos = (char*)ExecPath;
|
||||
for (;;)
|
||||
{
|
||||
// Look for whitespace
|
||||
if (!ParamStarted)
|
||||
{
|
||||
// Quotes starts quoted parameter
|
||||
if (*MatchPos == '"') {
|
||||
ParamStarted = true;
|
||||
OpenQuotes = true;
|
||||
StartPos = MatchPos+1; // Skip starting quote
|
||||
}
|
||||
// Non-whitespace starts normal parameter
|
||||
else if ((*MatchPos != ' ') && (*MatchPos != 0)) {
|
||||
ParamStarted = true;
|
||||
StartPos = MatchPos;
|
||||
}
|
||||
}
|
||||
else if (OpenQuotes)
|
||||
{
|
||||
// Another quote ends parameter
|
||||
if (*MatchPos == '"') {
|
||||
Len = MatchPos-StartPos-1; // Skip end quote
|
||||
Args[Count] = (char*)malloc( Len+1 );
|
||||
strncpy( Args[Count], StartPos, Len );
|
||||
Args[Count][Len] = 0;
|
||||
Count++;
|
||||
ParamStarted = false;
|
||||
OpenQuotes = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Whitespace ends parameter
|
||||
if ((*MatchPos == ' ') || (*MatchPos == 0)) {
|
||||
Len = MatchPos-StartPos;
|
||||
Args[Count] = (char*)malloc( Len+1 );
|
||||
strncpy( Args[Count], StartPos, Len );
|
||||
Args[Count][Len] = 0;
|
||||
Count++;
|
||||
ParamStarted = false;
|
||||
}
|
||||
}
|
||||
// Next char, unless NULL
|
||||
if (*MatchPos)
|
||||
MatchPos++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Check all parameters closed
|
||||
if (ParamStarted) {
|
||||
Count = 0;
|
||||
Args[0] = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set last Param to NULL
|
||||
Args[Count] = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -8,17 +8,19 @@
|
||||
#ifndef REDACORE_SELECTABLECORE_H_
|
||||
#define REDACORE_SELECTABLECORE_H_
|
||||
|
||||
// Standard C/C++ Libraries
|
||||
#include <stdio.h>
|
||||
#include <sys/wait.h>
|
||||
#include <string.h>
|
||||
|
||||
// redA Libraries
|
||||
#include "FunctionCore.h"
|
||||
|
||||
// Standard C/C++ Libraries
|
||||
#include <string.h>
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Types required for connections
|
||||
typedef enum { ctNone = 0, ctPort = 1, ctServer = 2, ctRemoteClient = 3, ctClient = 4 } EConnectType;
|
||||
const char ConnectTypeName[][15] = { "None", "Port", "Server", "RemoteClient", "Client" };
|
||||
typedef enum { ctNone = 0, ctPort = 1, ctForkPipe = 2, ctServer = 3, ctRemoteClient = 4, ctClient = 5 } EConnectType;
|
||||
const char ConnectTypeName[][15] = { "None", "Port", "ForkPipe", "Server", "RemoteClient", "Client" };
|
||||
|
||||
typedef enum { csNone = 0, csWaitingtoOpen = 1, csOpen = 2, csDataWaiting = 3, csClosed = 4, csFailed = 5 } EConnectState;
|
||||
const char ConnectStateName[][15] = { "None", "WaitingToOpen", "Open", "DataWaiting", "Closed", "Failed" };
|
||||
@@ -69,12 +71,16 @@ struct SHandle {
|
||||
char * Name;
|
||||
EConnectType Type;
|
||||
|
||||
char * FileName;
|
||||
// Type specific parameters
|
||||
char * Path; // Port (file)name or Exec path
|
||||
|
||||
char * Address;
|
||||
int PortNo;
|
||||
bool KeepAlive;
|
||||
pid_t ChildPID; // Forked child PID
|
||||
|
||||
char * Address; // Socket IP address
|
||||
int PortNo; // Socket port no
|
||||
bool KeepAlive; // Socket keep alive
|
||||
|
||||
// State
|
||||
int FD;
|
||||
EConnectState State;
|
||||
bool Auto;
|
||||
@@ -121,11 +127,12 @@ protected:
|
||||
timeval Timeout;
|
||||
|
||||
// Output
|
||||
CLogCore * Log;
|
||||
EDebugLevel DebugLevel;
|
||||
|
||||
public:
|
||||
// Life Cycle
|
||||
CSelect( long SelectTimeout, EDebugLevel DebugLevel );
|
||||
CSelect( long SelectTimeout, CLogCore * pLog, EDebugLevel DebugLevel );
|
||||
~CSelect();
|
||||
|
||||
// Manage FDs
|
||||
@@ -170,6 +177,9 @@ protected:
|
||||
// Port Operations
|
||||
virtual int OpenPort( THandle * Handle );
|
||||
|
||||
// ForkPipe Operations
|
||||
virtual int OpenForkPipe( THandle * Handle );
|
||||
|
||||
// Socket Operations
|
||||
virtual int OpenServerSocket( THandle * Handle );
|
||||
virtual int OpenRemoteClientSocket( THandle * Handle );
|
||||
@@ -187,9 +197,12 @@ protected:
|
||||
// Buffer operations
|
||||
virtual bool ProcessBuffer( THandle * Handle, bool Force );
|
||||
|
||||
// Specific operations
|
||||
bool BuildArgs( const char * ExecPath, int &Count, char * Args[] );
|
||||
|
||||
public:
|
||||
// Life Cycle
|
||||
CSelectableCore( const char * Name, CSelect * Selector, EDebugLevel pDebugLevel, int pOuputDisplay );
|
||||
CSelectableCore( const char * Name, CSelect * Selector, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay );
|
||||
~CSelectableCore();
|
||||
|
||||
// Finding Handles
|
||||
@@ -216,8 +229,9 @@ public:
|
||||
bool SetBuffers( THandle * Handle, int InBufSize, int OutBufSize, int InTimeout, const char * InMarker, int InMarkerLen );
|
||||
bool SerialConfig( THandle * Handle, int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait );
|
||||
|
||||
// Device Interface
|
||||
// File Interface
|
||||
bool SetPortHandle( THandle * Handle, const char * FileName );
|
||||
bool SetForkPipeHandle( THandle * Handle, const char * ExecPath );
|
||||
bool SetSocketHandle( THandle * Handle, EConnectType Type, const char * Address, const int PortNo, bool KeepAlive );
|
||||
bool ClearHandle( THandle * Handle );
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Global vars
|
||||
extern CLogCore * Log;
|
||||
extern char ProcessName[];
|
||||
|
||||
// Termination Vars
|
||||
@@ -87,12 +88,13 @@ void SignalTerminate( int sig )
|
||||
std::cerr << "\r\n" << ProcessName << ": ***********************************\n";
|
||||
|
||||
// Create Log Entry
|
||||
LogMessage( dlNone, dlNone, "%s: ** %s signal received [%d] **", ProcessName, SigName, TermCount );
|
||||
if (TermCount < MaxTermCount)
|
||||
LogMessage( dlNone, dlNone, "%s: ** Terminating normally... **", ProcessName );
|
||||
else
|
||||
LogMessage( dlNone, dlNone, "%s: ** Terminating immediately! **", ProcessName );
|
||||
|
||||
if (Log) Log->Message( dlNone, dlNone, "%s: ** %s signal received [%d] **", ProcessName, SigName, TermCount );
|
||||
if (TermCount < MaxTermCount) {
|
||||
if (Log) Log->Message( dlNone, dlNone, "%s: ** Terminating normally... **", ProcessName );
|
||||
}
|
||||
else {
|
||||
if (Log) Log->Message( dlNone, dlNone, "%s: ** Terminating immediately! **", ProcessName );
|
||||
}
|
||||
std::cerr << ProcessName << ": ***********************************\n\n";
|
||||
|
||||
if (TermCount >= MaxTermCount)
|
||||
@@ -121,8 +123,8 @@ void SignalAbort( int sig )
|
||||
std::cerr << "\n" << ProcessName << ": ********************************\n";
|
||||
|
||||
// Create Log Entry - but don't post
|
||||
LogMessage( dlNone, dlNone, "%s: ** %s signal received **", ProcessName, SigName );
|
||||
LogMessage( dlNone, dlNone, "%s: ** Terminating immediately! **", ProcessName );
|
||||
if (Log) Log->Message( dlNone, dlNone, "%s: ** %s signal received **", ProcessName, SigName );
|
||||
if (Log) Log->Message( dlNone, dlNone, "%s: ** Terminating immediately! **", ProcessName );
|
||||
|
||||
std::cerr << ProcessName << ": ********************************\n\n";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user