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:
Charl Wentzel
2016-08-22 12:14:53 +02:00
parent eaace97ec9
commit 5ea05d119e
10 changed files with 366 additions and 125 deletions

View File

@@ -27,8 +27,8 @@ const float PI = 3.1415927;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CFileCore::CFileCore( const char * Name, EDebugLevel pDebugLevel, int pOuputDisplay ) : CFileCore::CFileCore( const char * Name, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay ) :
CFunctionCore( Name, pDebugLevel, pOuputDisplay ) CFunctionCore( Name, pLog, pDebugLevel, pOuputDisplay )
{ {
FirstFile = NULL; FirstFile = NULL;
@@ -143,7 +143,7 @@ bool CFileCore::OpenFile( TFileHandle * FileHandle )
// temp // temp
//char FilePath[50]; //char FilePath[50];
//sprintf( FilePath, "%s%03d", FileHandle->Path, x++ ); //sprintf( FilePath, "%s%03d", FileHandle->Path, x++ );
//LogMessage( DebugLevel, dlNone, "f: %s", FilePath ); //if (Log) Log->Message( DebugLevel, dlNone, "f: %s", FilePath );
// temp // temp
// GEt file handle // GEt file handle
@@ -160,7 +160,7 @@ bool CFileCore::OpenFile( TFileHandle * FileHandle )
// temp // temp
// Report result // 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)) if (!isOpen(FileHandle))
{ {
// Report result // 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; return false;
} }
@@ -192,13 +192,13 @@ bool CFileCore::CloseFile( TFileHandle * FileHandle )
// Report result // Report result
if (!isOpen(FileHandle)) { 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 { } 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 // 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 // temp
} }
@@ -282,7 +282,7 @@ int CFileCore::Input( const char * IOName, const char * Data, int MaxLen )
if (!(FileHandle = GetFile( IOName ))) if (!(FileHandle = GetFile( IOName )))
{ {
// Log event // 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; return 0;
} }

View File

@@ -65,7 +65,7 @@ private:
public: public:
// Life cycle // Life cycle
CFileCore( const char * Name, EDebugLevel pDebugLevel, int pOuputDisplay ); CFileCore( const char * Name, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay );
~CFileCore(); ~CFileCore();
// Manage files // Manage files

View File

@@ -22,7 +22,7 @@ extern char ProcessName[];
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Life cycle // Life cycle
CFunctionCore::CFunctionCore( const char * FunctionName, EDebugLevel pDebugLevel, int pOuputDisplay ) CFunctionCore::CFunctionCore( const char * FunctionName, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay )
{ {
// Set name // Set name
if (FunctionName) { if (FunctionName) {
@@ -37,11 +37,12 @@ CFunctionCore::CFunctionCore( const char * FunctionName, EDebugLevel pDebugLevel
FirstIO = NULL; FirstIO = NULL;
// Output // Output
Log = pLog;
OutputDisplay = pOuputDisplay; OutputDisplay = pOuputDisplay;
DebugLevel = pDebugLevel; DebugLevel = pDebugLevel;
// Report status // 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 // 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 // Destroy Name
if (Name) { if (Name) {
@@ -122,7 +123,7 @@ TLocalIO * CFunctionCore::AddLocalIO( const char * IOName )
strcpy( (*LocalIO)->Name, IOName ); strcpy( (*LocalIO)->Name, IOName );
// Log Event // 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; return *LocalIO;
@@ -159,7 +160,7 @@ bool CFunctionCore::AddInput( const char * IOName, CFunctionCore * OutFunction,
strcpy( (*LinkedIO)->IOName, OutputName ); strcpy( (*LinkedIO)->IOName, OutputName );
// Log Event // 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 // Link Return direction as well
@@ -200,7 +201,7 @@ bool CFunctionCore::AddOutput( const char * IOName, CFunctionCore * InFunction,
strcpy( (*LinkedIO)->IOName, InputName ); strcpy( (*LinkedIO)->IOName, InputName );
// Log Event // 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 // Link return direction as well
@@ -229,12 +230,12 @@ int CFunctionCore::Input( const char * IOName, const char * Data, int MaxLen )
if (!(LocalIO = GetLocalIO( IOName ))) if (!(LocalIO = GetLocalIO( IOName )))
{ {
// Log event // 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; return 0;
} }
// Log event // 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 processed bytes
return MaxLen; return MaxLen;
@@ -256,7 +257,7 @@ int CFunctionCore::Output( const char * IOName, const char * Data, int Len )
if (!(LocalIO = GetLocalIO( IOName ))) if (!(LocalIO = GetLocalIO( IOName )))
{ {
// Log Event // 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; return 0;
} }
@@ -277,7 +278,7 @@ int CFunctionCore::Output( const TLocalIO * LocalIO, const char * Data, int Len
} }
// Log event // 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 // Pass output to all linked inputs
Output = LocalIO->FirstOutput; Output = LocalIO->FirstOutput;

View File

@@ -56,6 +56,7 @@ protected:
TLocalIO * FirstIO; TLocalIO * FirstIO;
// Output // Output
CLogCore * Log;
EDebugLevel DebugLevel; EDebugLevel DebugLevel;
int OutputDisplay; int OutputDisplay;
@@ -73,7 +74,7 @@ protected:
public: public:
// Life cycle // Life cycle
CFunctionCore( const char * ObjectName, EDebugLevel pDebugLevel, int pOuputDisplay ); CFunctionCore( const char * ObjectName, CLogCore * pLog, EDebugLevel pDebugLevel, int pOuputDisplay );
virtual ~CFunctionCore(); virtual ~CFunctionCore();
// Miscellaneous // Miscellaneous

View File

@@ -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; va_list ArgPtr;
@@ -31,20 +37,20 @@ bool LogMessage( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const char * Form
return false; return false;
// Check debug level // Check debug level
if (MsgLevel > DebugLevel) { if (!FileOutput || (MsgLevel > DebugLevel)) {
return true; return true;
} }
// Show normal output // Show normal output
va_start( ArgPtr, Format ); va_start( ArgPtr, Format );
vprintf( Format, ArgPtr ); vfprintf( FileOutput, Format, ArgPtr );
printf( "\r\n" ); fprintf( FileOutput, "\r\n" );
va_end( ArgPtr ); va_end( ArgPtr );
return true; 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; va_list ArgPtr;
@@ -53,7 +59,7 @@ bool ShowOutput( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show,
return false; return false;
// Check debug level // Check debug level
if (MsgLevel > DebugLevel) { if (!FileOutput || (MsgLevel > DebugLevel)) {
return true; return true;
} }
@@ -64,7 +70,7 @@ bool ShowOutput( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show,
// Show Lead // Show Lead
if (Format && *Format) { if (Format && *Format) {
va_start( ArgPtr, Format ); va_start( ArgPtr, Format );
vprintf( Format, ArgPtr ); vfprintf( FileOutput, Format, ArgPtr );
va_end( ArgPtr ); va_end( ArgPtr );
} }
@@ -72,11 +78,11 @@ bool ShowOutput( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show,
if (Show & OUT_COUNT) if (Show & OUT_COUNT)
{ {
// Print byte count // Print byte count
printf( " [%d] ", Len ); fprintf( FileOutput, " [%d] ", Len );
// EOL if only count wanted // EOL if only count wanted
if (Show & OUT_COUNT) { 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) { if (Show & OUT_ASIS) {
// Print entire buffer as is (line feeds included) // Print entire buffer as is (line feeds included)
printf( "%s", Buffer ); fprintf( FileOutput, "%s", Buffer );
} }
else { else {
// Ignore \r\n // Ignore \r\n
for (int i=0; i<Len; i++) { for (int i=0; i<Len; i++) {
if ((Buffer[i] < 32) || (Buffer[i] > 126)) { if ((Buffer[i] < 32) || (Buffer[i] > 126)) {
if ((Show & OUT_CRLF) && ((Buffer[i] == '\r') || (Buffer[i] == '\n'))) if ((Show & OUT_CRLF) && ((Buffer[i] == '\r') || (Buffer[i] == '\n')))
printf( "%c", Buffer[i] ); fprintf( FileOutput, "%c", Buffer[i] );
else else
printf( "." ); fprintf( FileOutput, "." );
} }
else { else {
printf( "%c", Buffer[i] ); fprintf( FileOutput, "%c", Buffer[i] );
} }
} }
} }
// Add EOL if not present or ignored // Add EOL if not present or ignored
if (!(Show & (OUT_ASIS | OUT_CRLF)) || (Buffer[Len-1] != '\n')) { 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 // Print Hex values of individual bytes
for (int i=0; i<Len; i++) { 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 // Show Binary output
@@ -122,10 +128,10 @@ bool ShowOutput( EDebugLevel DebugLevel, EDebugLevel MsgLevel, const short Show,
// Print each byte as 8-bit binary // Print each byte as 8-bit binary
for (int i=0; i<Len; i++) { for (int i=0; i<Len; i++) {
for (int j=0; j<8; j++) { 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; return true;
} }

View File

@@ -12,7 +12,7 @@
/* none */ /* none */
// Standard C/C++ Libraries // 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_ */ #endif /* REDACORE_OGCORE_H_ */

View File

@@ -23,7 +23,7 @@ extern char ProcessName[];
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Create Select // Create Select
CSelect::CSelect( long SelectTimeout, EDebugLevel pDebugLevel ) CSelect::CSelect( long SelectTimeout, CLogCore * pLog, EDebugLevel pDebugLevel )
{ {
// Clear List // Clear List
FirstHandle = NULL; FirstHandle = NULL;
@@ -39,10 +39,11 @@ CSelect::CSelect( long SelectTimeout, EDebugLevel pDebugLevel )
SetInterval( &Timeout, SelectTimeout ); SetInterval( &Timeout, SelectTimeout );
// Output // Output
Log = pLog;
DebugLevel = pDebugLevel; DebugLevel = pDebugLevel;
// Show status // 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 // Show status
LogMessage( DebugLevel, dlLow, "%s: Select - Destroyed", ProcessName ); if (Log) Log->Message( DebugLevel, dlLow, "%s: Select - Destroyed", ProcessName );
return; return;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -105,7 +106,7 @@ void CSelect::Add( int FD, bool Read, bool Write, CSelectableCore * Function )
FD_SET( FD, &ReadTestFDS ); FD_SET( FD, &ReadTestFDS );
// Log event // 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 // Add Write Select
@@ -114,7 +115,7 @@ void CSelect::Add( int FD, bool Read, bool Write, CSelectableCore * Function )
FD_SET( FD, &WriteTestFDS ); FD_SET( FD, &WriteTestFDS );
// Log event // 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 // Check Maximum File Handle
@@ -142,7 +143,7 @@ void CSelect::Remove( int FD, bool Read, bool Write )
FD_CLR( FD, &ReadTestFDS); FD_CLR( FD, &ReadTestFDS);
// Log event // 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 // Remove from set for select write check
@@ -151,7 +152,7 @@ void CSelect::Remove( int FD, bool Read, bool Write )
FD_CLR( FD, &WriteTestFDS); FD_CLR( FD, &WriteTestFDS);
// Log event // 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 // 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 ); Events = select( MaxFD, &ReadFDS, &WriteFDS, (fd_set*)NULL, &STimeout );
if (Events < 0) if (Events < 0)
{ {
LogMessage( DebugLevel, dlHigh, "Select: Select operation failed" ); if (Log) Log->Message( DebugLevel, dlHigh, "Select: Select operation failed" );
return false; return false;
} }

View File

@@ -30,8 +30,8 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
CSelectableCore::CSelectableCore( const char * Name, CSelect * Selector, EDebugLevel pDebugLevel, int pOutputDisplay ) : CSelectableCore::CSelectableCore( const char * Name, CSelect * Selector, CLogCore * pLog, EDebugLevel pDebugLevel, int pOutputDisplay ) :
CFunctionCore( Name, pDebugLevel, pOutputDisplay ) CFunctionCore( Name, pLog, pDebugLevel, pOutputDisplay )
{ {
// Handles // Handles
FirstHandle = NULL; FirstHandle = NULL;
@@ -85,7 +85,7 @@ THandle * CSelectableCore::CreateHandle( const char * HandleName, bool CreateLo
(*Handle)->FD = -1; (*Handle)->FD = -1;
// Log event // 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 // Create Matching IO point
@@ -117,7 +117,7 @@ bool CSelectableCore::RemoveHandle( THandle * Handle )
} }
// Log event // 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 // Destroy Child handle
DestroyHandle( Handle ); DestroyHandle( Handle );
@@ -134,8 +134,8 @@ bool CSelectableCore::DestroyHandle( THandle * Handle )
// Clear parameters // Clear parameters
if (Handle->Name) if (Handle->Name)
free( Handle->Name ); free( Handle->Name );
if (Handle->FileName) if (Handle->Path)
free( Handle->FileName ); free( Handle->Path );
if (Handle->Address) if (Handle->Address)
free( Handle->Address ); free( Handle->Address );
@@ -166,16 +166,41 @@ bool CSelectableCore::SetPortHandle( THandle * Handle, const char * FileName )
Handle->Type = ctPort; Handle->Type = ctPort;
// Clear File Name // Clear File Name
if (Handle->FileName) { if (Handle->Path) {
free( Handle->FileName ); free( Handle->Path );
} }
// Set name // Set name
Handle->FileName = (char*)malloc( strlen(FileName)+1 ); Handle->Path = (char*)malloc( strlen(FileName)+1 );
strcpy( Handle->FileName, FileName ); strcpy( Handle->Path, FileName );
// Log event // 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; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -202,7 +227,7 @@ bool CSelectableCore::SetSocketHandle( THandle * Handle, EConnectType Type, con
Handle->PortNo = PortNo; Handle->PortNo = PortNo;
// Log event // 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; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -215,9 +240,9 @@ bool CSelectableCore::ClearHandle( THandle * Handle )
} }
// Reset Type related parameters // Reset Type related parameters
if (Handle->FileName) { if (Handle->Path) {
free( Handle->FileName ); free( Handle->Path );
Handle->FileName = NULL; Handle->Path = NULL;
} }
if (Handle->Address) { if (Handle->Address) {
free( Handle->Address ); free( Handle->Address );
@@ -229,7 +254,7 @@ bool CSelectableCore::ClearHandle( THandle * Handle )
Handle->Type = ctNone; Handle->Type = ctNone;
// Log event // 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; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -298,24 +323,24 @@ int CSelectableCore::OpenPort( THandle * Handle )
} }
// Check if port exits // Check if port exits
if (access( Handle->FileName, F_OK ) != 0) if (access( Handle->Path, F_OK ) != 0)
{ {
// Log event // 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; return -1;
} }
// Open Port // Open Port
Handle->FD = open( Handle->FileName, O_RDWR ); Handle->FD = open( Handle->Path, O_RDWR );
if (Handle->FD == -1) if (Handle->FD == -1)
{ {
// Log event // 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; return -1;
} }
// Log Event // 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 // Add to Select Lists
if (Select) { 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 ) int CSelectableCore::OpenServerSocket( THandle * Handle )
{ {
socklen_t addr_len; socklen_t addr_len;
@@ -360,7 +481,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
if ((Handle->FD = socket(AF_INET, SOCK_STREAM, 0)) < 0) if ((Handle->FD = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{ {
// Log Event // 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 // Set state
Handle->State = csFailed; 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)) (setsockopt( Handle->FD, SOL_SOCKET, SO_REUSEADDR, &Reuse_opt, sizeof(Reuse_opt)) == -1))
{ {
// Log Event // 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 // Set state
Handle->State = csFailed; 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) )) (setsockopt( Handle->FD, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ))
{ {
// Log Event // 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 // Set state
Handle->State = csFailed; Handle->State = csFailed;
@@ -402,7 +523,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
if (bind( Handle->FD, (struct sockaddr *)&address, addr_len ) < 0) if (bind( Handle->FD, (struct sockaddr *)&address, addr_len ) < 0)
{ {
// Log Event // 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 // Set state
close( Handle->FD ); close( Handle->FD );
@@ -415,7 +536,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
if (listen( Handle->FD, 5 ) < 0) if (listen( Handle->FD, 5 ) < 0)
{ {
// Log Event // 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 // Set state
close( Handle->FD ); close( Handle->FD );
@@ -425,7 +546,7 @@ int CSelectableCore::OpenServerSocket( THandle * Handle )
}; };
// Log Event // 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 // Add to Select Lists
if (Select) { if (Select) {
@@ -461,10 +582,12 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
if ((ClientFD = accept( Handle->FD, (struct sockaddr *)&address, &addr_len)) == -1) if ((ClientFD = accept( Handle->FD, (struct sockaddr *)&address, &addr_len)) == -1)
{ {
// Log Event // Log Event
if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
LogMessage( DebugLevel, dlMedium, "%s: Handle '%s' - Server failed to accept blocking connection (%s)", Name, Handle->Name, strerror(errno) ); if (Log) Log->Message( 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) ); else {
if (Log) Log->Message( DebugLevel, dlMedium, "%s: Handle '%s' - Server failed to accept connection (%s)", Name, Handle->Name, strerror(errno) );
}
return -1; return -1;
} }
@@ -497,7 +620,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
(*RemoteClient)->State = csWaitingtoOpen; (*RemoteClient)->State = csWaitingtoOpen;
// Log Event // 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 // Add to Select Lists
if (Select) { if (Select) {
@@ -517,7 +640,7 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
else if (Handle->State == csWaitingtoOpen) else if (Handle->State == csWaitingtoOpen)
{ {
// Log Event // 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 // Update state
Handle->State = csOpen; Handle->State = csOpen;
@@ -551,7 +674,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
if ((Handle->FD = socket( AF_INET, SOCK_STREAM, 0 )) < 0) if ((Handle->FD = socket( AF_INET, SOCK_STREAM, 0 )) < 0)
{ {
// Log Event // 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 // Set Status
Handle->State = csFailed; 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) )) (setsockopt( Handle->FD, SOL_TCP, TCP_KEEPINTVL, &TCPint_opt, sizeof(TCPint_opt)) == -1) ))
{ {
// Log Event // 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 // Set State
close( Handle->FD ); close( Handle->FD );
@@ -588,7 +711,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
if (!connect( Handle->FD, (struct sockaddr *)&address, addr_len )) 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 // Add to Select Lists
if (Select) { if (Select) {
@@ -602,7 +725,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
else if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EALREADY)) else if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EALREADY))
{ {
// Log Event // 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 // Add to Select Lists
if (Select) { if (Select) {
@@ -616,7 +739,7 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
else else
{ {
// Log Event // 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 // Remove from Select List
if (Select) { if (Select) {
@@ -651,6 +774,9 @@ int CSelectableCore::Open( THandle * Handle )
case ctPort : case ctPort :
FD = OpenPort( Handle ); FD = OpenPort( Handle );
break; break;
case ctForkPipe :
FD = OpenForkPipe( Handle );
break;
case ctServer : case ctServer :
FD = OpenServerSocket( Handle ); FD = OpenServerSocket( Handle );
break; break;
@@ -709,24 +835,29 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
{ {
case ctPort: case ctPort:
// Log Event // 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; break;
case ctServer: 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; break;
case ctRemoteClient: 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; break;
case ctClient: 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; break;
case ctNone: case ctNone:
default: 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; break;
}; };
@@ -754,7 +885,7 @@ bool CSelectableCore::Read( THandle * Handle )
} }
// Log Read Event // 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 // Check for closing/opening event on Socket
if (Handle->Type == ctServer) if (Handle->Type == ctServer)
@@ -830,7 +961,7 @@ bool CSelectableCore::Write( THandle * Handle )
} }
// Log Ready for Write Event // 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) if (Handle->State == csWaitingtoOpen)
{ {
@@ -857,7 +988,7 @@ bool CSelectableCore::Write( THandle * Handle )
if (DebugLevel >= dlHigh) { if (DebugLevel >= dlHigh) {
// Show event // Show event
Len = Handle->OutBuffer->Peek( &Data ); 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 // Update Buffer
@@ -902,7 +1033,7 @@ bool CSelectableCore::ProcessBuffer( THandle * Handle, bool Force )
{ {
// Show Packet // Show Packet
Len = Handle->InBuffer->Peek( &Data ); 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 // Write buffer to Outputs
if (Handle->Type == ctRemoteClient) { if (Handle->Type == ctRemoteClient) {
@@ -921,7 +1052,7 @@ bool CSelectableCore::ProcessBuffer( THandle * Handle, bool Force )
{ {
// Show Packet // Show Packet
Len = Handle->InBuffer->Peek( &Data, 0, Pos+1 ); 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 // Write buffer to Outputs
if (Handle->Type == ctRemoteClient) { if (Handle->Type == ctRemoteClient) {
@@ -1014,19 +1145,19 @@ int CSelectableCore::Input( const char * IOName, const char * Data, int Len )
if (!(Handle = GetHandle( IOName ))) if (!(Handle = GetHandle( IOName )))
{ {
// Log event // 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; return 0;
} }
// Check that handle is open // Check that handle is open
else if (Handle->State != csOpen) else if (Handle->State != csOpen)
{ {
// Log event // 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; return 0;
} }
// Log event // 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) 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 ); BytesWritten = WriteToFD( ChildHandle->FD, Data, Len, true );
// Show event // 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 // Next
@@ -1080,7 +1211,7 @@ int CSelectableCore::Input( const char * IOName, const char * Data, int Len )
else else
{ {
// Show event // 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 // Write directly to handle
BytesWritten = WriteToFD( Handle->FD, Data, Len, true ); 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) if (tcsetattr( Handle->FD, TCSANOW, &newtio ) != 0)
{ {
// Log event // 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; return false;
} }
// Port configured // Port configured
// Log event // 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; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -8,17 +8,19 @@
#ifndef REDACORE_SELECTABLECORE_H_ #ifndef REDACORE_SELECTABLECORE_H_
#define REDACORE_SELECTABLECORE_H_ #define REDACORE_SELECTABLECORE_H_
// Standard C/C++ Libraries
#include <stdio.h>
#include <sys/wait.h>
#include <string.h>
// redA Libraries // redA Libraries
#include "FunctionCore.h" #include "FunctionCore.h"
// Standard C/C++ Libraries
#include <string.h>
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Types required for connections // Types required for connections
typedef enum { ctNone = 0, ctPort = 1, ctServer = 2, ctRemoteClient = 3, ctClient = 4 } EConnectType; typedef enum { ctNone = 0, ctPort = 1, ctForkPipe = 2, ctServer = 3, ctRemoteClient = 4, ctClient = 5 } EConnectType;
const char ConnectTypeName[][15] = { "None", "Port", "Server", "RemoteClient", "Client" }; 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; 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" }; const char ConnectStateName[][15] = { "None", "WaitingToOpen", "Open", "DataWaiting", "Closed", "Failed" };
@@ -69,12 +71,16 @@ struct SHandle {
char * Name; char * Name;
EConnectType Type; EConnectType Type;
char * FileName; // Type specific parameters
char * Path; // Port (file)name or Exec path
char * Address; pid_t ChildPID; // Forked child PID
int PortNo;
bool KeepAlive;
char * Address; // Socket IP address
int PortNo; // Socket port no
bool KeepAlive; // Socket keep alive
// State
int FD; int FD;
EConnectState State; EConnectState State;
bool Auto; bool Auto;
@@ -121,11 +127,12 @@ protected:
timeval Timeout; timeval Timeout;
// Output // Output
CLogCore * Log;
EDebugLevel DebugLevel; EDebugLevel DebugLevel;
public: public:
// Life Cycle // Life Cycle
CSelect( long SelectTimeout, EDebugLevel DebugLevel ); CSelect( long SelectTimeout, CLogCore * pLog, EDebugLevel DebugLevel );
~CSelect(); ~CSelect();
// Manage FDs // Manage FDs
@@ -170,6 +177,9 @@ protected:
// Port Operations // Port Operations
virtual int OpenPort( THandle * Handle ); virtual int OpenPort( THandle * Handle );
// ForkPipe Operations
virtual int OpenForkPipe( THandle * Handle );
// Socket Operations // Socket Operations
virtual int OpenServerSocket( THandle * Handle ); virtual int OpenServerSocket( THandle * Handle );
virtual int OpenRemoteClientSocket( THandle * Handle ); virtual int OpenRemoteClientSocket( THandle * Handle );
@@ -187,9 +197,12 @@ protected:
// Buffer operations // Buffer operations
virtual bool ProcessBuffer( THandle * Handle, bool Force ); virtual bool ProcessBuffer( THandle * Handle, bool Force );
// Specific operations
bool BuildArgs( const char * ExecPath, int &Count, char * Args[] );
public: public:
// Life Cycle // 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(); ~CSelectableCore();
// Finding Handles // Finding Handles
@@ -216,8 +229,9 @@ public:
bool SetBuffers( THandle * Handle, int InBufSize, int OutBufSize, int InTimeout, const char * InMarker, int InMarkerLen ); 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 ); 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 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 SetSocketHandle( THandle * Handle, EConnectType Type, const char * Address, const int PortNo, bool KeepAlive );
bool ClearHandle( THandle * Handle ); bool ClearHandle( THandle * Handle );

View File

@@ -20,6 +20,7 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Global vars // Global vars
extern CLogCore * Log;
extern char ProcessName[]; extern char ProcessName[];
// Termination Vars // Termination Vars
@@ -87,12 +88,13 @@ void SignalTerminate( int sig )
std::cerr << "\r\n" << ProcessName << ": ***********************************\n"; std::cerr << "\r\n" << ProcessName << ": ***********************************\n";
// Create Log Entry // Create Log Entry
LogMessage( dlNone, dlNone, "%s: ** %s signal received [%d] **", ProcessName, SigName, TermCount ); if (Log) Log->Message( dlNone, dlNone, "%s: ** %s signal received [%d] **", ProcessName, SigName, TermCount );
if (TermCount < MaxTermCount) if (TermCount < MaxTermCount) {
LogMessage( dlNone, dlNone, "%s: ** Terminating normally... **", ProcessName ); if (Log) Log->Message( dlNone, dlNone, "%s: ** Terminating normally... **", ProcessName );
else }
LogMessage( dlNone, dlNone, "%s: ** Terminating immediately! **", ProcessName ); else {
if (Log) Log->Message( dlNone, dlNone, "%s: ** Terminating immediately! **", ProcessName );
}
std::cerr << ProcessName << ": ***********************************\n\n"; std::cerr << ProcessName << ": ***********************************\n\n";
if (TermCount >= MaxTermCount) if (TermCount >= MaxTermCount)
@@ -121,8 +123,8 @@ void SignalAbort( int sig )
std::cerr << "\n" << ProcessName << ": ********************************\n"; std::cerr << "\n" << ProcessName << ": ********************************\n";
// Create Log Entry - but don't post // Create Log Entry - but don't post
LogMessage( dlNone, dlNone, "%s: ** %s signal received **", ProcessName, SigName ); if (Log) Log->Message( dlNone, dlNone, "%s: ** %s signal received **", ProcessName, SigName );
LogMessage( dlNone, dlNone, "%s: ** Terminating immediately! **", ProcessName ); if (Log) Log->Message( dlNone, dlNone, "%s: ** Terminating immediately! **", ProcessName );
std::cerr << ProcessName << ": ********************************\n\n"; std::cerr << ProcessName << ": ********************************\n\n";