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

@@ -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;
}
//---------------------------------------------------------------------------