- readd named pipe support for linux by Christoph_vW

- simplify named pipe code
- only allocate buffer for reading once 
- dont format default hdd if it exists
- delay read at right position
- fix ROS_DELAY_READ option in config file - value is expected to be in seconds not milliseconds

svn path=/trunk/; revision=28854
This commit is contained in:
Johannes Anderwald 2007-09-04 19:53:49 +00:00
parent a04c49f61c
commit a1de0509ed
5 changed files with 135 additions and 94 deletions

View file

@ -20,15 +20,22 @@ namespace System_
using std::vector; using std::vector;
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
NamedPipeReader::NamedPipeReader() : DataSource(), h_Pipe(NULLVAL) NamedPipeReader::NamedPipeReader() : DataSource(), h_Pipe(NULLVAL), m_Buffer(0)
{ {
#ifdef UNICODE
m_WBuffer = 0;
#endif
} }
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
NamedPipeReader::~NamedPipeReader() NamedPipeReader::~NamedPipeReader()
{ {
if (m_Buffer)
free(m_Buffer);
#ifdef UNICODE
if (m_WBuffer)
free(m_WBuffer);
#endif
} }
bool NamedPipeReader::isSourceOpen() bool NamedPipeReader::isSourceOpen()
@ -45,15 +52,15 @@ namespace System_
cerr << "NamedPipeReader::openPipe> pipe already open" << endl; cerr << "NamedPipeReader::openPipe> pipe already open" << endl;
return false; return false;
} }
#ifndef __LINUX__
h_Pipe = CreateFile("\\\\.\\pipe\\qemu", //PipeCmd.c_str(), h_Pipe = CreateFile("\\\\.\\pipe\\qemu", //PipeCmd.c_str(),
GENERIC_WRITE | GENERIC_READ, GENERIC_WRITE | GENERIC_READ,
0, 0,
NULL, NULL,
OPEN_EXISTING, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL,
(HANDLE) (HANDLE)
NULL); NULL);
if(INVALID_HANDLE_VALUE == h_Pipe) { if(INVALID_HANDLE_VALUE == h_Pipe) {
cerr << "NamedPipeReader::openPipe> failed to open pipe " << PipeCmd << " Error:" << GetLastError() << endl; cerr << "NamedPipeReader::openPipe> failed to open pipe " << PipeCmd << " Error:" << GetLastError() << endl;
@ -61,28 +68,48 @@ namespace System_
return false; return false;
} }
else else
{
cout << "NamedPipeReader::openPipe> successfully opened pipe" << endl;
m_BufferLength = 100;
m_Buffer = (char*)malloc(sizeof(char) * m_BufferLength);
#ifdef UNICODE
m_WBuffer = (WCHAR*)malloc(sizeof(WCHAR) * m_BufferLength);
#endif
ConnectNamedPipe(h_Pipe,
0);
return true;
}
#else
h_Pipe = open("PipeCmd.c_str()", O_RDONLY);
if(INVALID_HANDLE_VALUE == h_Pipe) {
cerr << "NamedPipeReader::openPipe> failed to open pipe " << PipeCmd << endl;
h_Pipe = NULLVAL;
return false;
}
else
{ {
cout << "NamedPipeReader::openPipe> successfully opened pipe" << endl; cout << "NamedPipeReader::openPipe> successfully opened pipe" << endl;
return true; return true;
} }
#endif
ConnectNamedPipe(
h_Pipe,
0);
} }
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
bool NamedPipeReader::closeSource() bool NamedPipeReader::closeSource()
{ {
if (h_Pipe == INVALID_HANDLE_VALUE) if (h_Pipe == NULLVAL)
{ {
cerr << "NamedPipeReader::closePipe> pipe is not open" << endl; cerr << "NamedPipeReader::closePipe> pipe is not open" << endl;
return false; return false;
} }
#ifdef __LINUX__
close(h_Pipe);
#else
DisconnectNamedPipe(h_Pipe); DisconnectNamedPipe(h_Pipe);
CloseHandle(h_Pipe); CloseHandle(h_Pipe);
#endif
h_Pipe = NULLVAL; h_Pipe = NULLVAL;
return true; return true;
} }
@ -173,70 +200,75 @@ namespace System_
append_line = false; append_line = false;
} }
} }
//---------------------------------------------------------------------------------------
bool NamedPipeReader::readPipe(char * buffer, int bufferlength, long & read)
{
#ifdef __LINUX__
long cbRead = read(h_Pipe,
buffer,
(bufferlength-1) * sizeof(char));
#else
DWORD cbRead = 0;
BOOL fSuccess = ReadFile(h_Pipe,
buffer,
(bufferlength-1) * sizeof(char),
&cbRead,
NULL);
if (!fSuccess && GetLastError() != ERROR_MORE_DATA)
return false;
#endif
read = cbRead;
return true;
}
//--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
bool NamedPipeReader::readSource(vector<string> & vect) bool NamedPipeReader::readSource(vector<string> & vect)
{ {
char * localbuf;
DWORD localsize = 100;
size_t lines = vect.size (); size_t lines = vect.size ();
BOOL fSuccess; if (h_Pipe == NULLVAL)
localbuf = (char*) HeapAlloc(GetProcessHeap(), 0, localsize * sizeof(char)); {
cerr << "Error: pipe is not open" << endl;
return false;
}
if (!m_Buffer)
{
cerr << "Error: no memory" << endl;
}
#ifdef UNICODE #ifdef UNICODE
wchar_t * wbuf = (WCHAR*) HeapAlloc(GetProcessHeap(), 0, localsize * sizeof(wchar_t)); if (!m_WBuffer)
#endif /* UNICODE */ {
if (localbuf != NULL) cerr << "Error: no memory" << endl;
}
#endif
bool append_line = false;
do
{ {
bool append_line = false; memset(m_Buffer, 0x0, m_BufferLength * sizeof(char));
do long cbRead = 0;
{
DWORD cbRead;
do
{
ZeroMemory(localbuf, localsize * sizeof(char));
#ifdef UNICODE
ZeroMemory(wbuf, localsize * sizeof(wchar_t));
#endif /* UNICODE */
fSuccess = ReadFile( if (!readPipe(m_Buffer, 100, cbRead))
h_Pipe, break;
localbuf,
(localsize-1) * sizeof(char),
&cbRead,
NULL);
if (! fSuccess && GetLastError() != ERROR_MORE_DATA)
break;
#ifdef UNICODE #ifdef UNICODE
if (UnicodeConverter::ansi2Unicode(localbuf, wbuf, cbRead)) memset(m_WBuffer, 0x0, m_BufferLength * sizeof(WCHAR));
{ if (!UnicodeConverter::ansi2Unicode(m_Buffer, m_WBuffer, cbRead))
extractLines(wbuf, vect, append_line, cbRead); break;
} extractLines(m_WBuffer, vect, append_line, cbRead);
#else /* UNICODE */ #endif
extractLines(localbuf, vect, append_line, cbRead); extractLines(m_Buffer, vect, append_line, cbRead);
#endif /* UNICODE */
} while (!fSuccess); // repeat loop if ERROR_MORE_DATA
} while (append_line);
if (!fSuccess) }while (append_line);
return 0;
HeapFree(GetProcessHeap(), 0, localbuf); return (vect.size () - lines);
#ifdef UNICODE }
HeapFree(GetProcessHeap(), 0, wbuf);
#endif /* UNICODE */
}
else
{
return 0;
}
return (vect.size () - lines);
}
} // end of namespace System_ } // end of namespace System_

View file

@ -120,8 +120,15 @@ protected:
void extractLines(TCHAR * buffer, std::vector<string> & vect, bool & append_line, unsigned long cbRead); void extractLines(TCHAR * buffer, std::vector<string> & vect, bool & append_line, unsigned long cbRead);
bool readPipe(char * buffer, int bufferlength, long & read);
HANDLE h_Pipe; HANDLE h_Pipe;
char * m_Buffer;
int m_BufferLength;
#ifdef UNICODE
WCHAR * m_WBuffer;
#endif
}; // end of class NamedPipeReader }; // end of class NamedPipeReader

View file

@ -247,12 +247,14 @@ namespace Sysreg_
} }
#ifdef __LINUX__ #ifdef __LINUX__
pipe = _T("stdio"); pipe = _T("pipe:/tmp/qemu");
m_Src = _T(""); m_Src = _T("/tmp/qemu");
qemudir = _T("/usr/share/qemu"); qemudir = _T("/usr/share/qemu");
m_DebugPort = _T("pipe");
#else #else
pipe = _T("pipe:qemu"); pipe = _T("pipe:qemu");
m_Src = _T("\\\\.\\pipe\\qemu"); m_Src = _T("\\\\.\\pipe\\qemu");
m_DebugPort = _T("pipe");
if (!getQemuDir(qemudir)) if (!getQemuDir(qemudir))
{ {
return false; return false;
@ -322,29 +324,26 @@ namespace Sysreg_
pos = pipe.find(_T("pipe:")); pos = pipe.find(_T("pipe:"));
if (pos == 0) if (pos == 0)
{ {
#ifdef __LINUX__
cerr << "Error: reading from pipes is not supported with linux hosts - use stdio" << endl;
return false;
}
#else
pipe = pipe.substr(pos + 5, pipe.size() - pos - 5); pipe = pipe.substr(pos + 5, pipe.size() - pos - 5);
pos = pipe.find(_T(" ")); pos = pipe.find(_T(" "));
if (pos != string::npos) if (pos != string::npos)
{ {
m_Src = _T("\\\\.\\pipe\\") + pipe.substr(0, pos); pipe = pipe.substr(0, pos);
} }
else #ifdef __LINUX__
{ m_Src = pipe;
m_Src = _T("\\\\.\\pipe\\") + pipe; #else
} m_Src = _T("\\\\.\\pipe\\") + pipe.substr(0, pos);
#endif
m_DebugPort = _T("pipe");
return true; return true;
} }
#endif
pos = pipe.find(_T("stdio")); pos = pipe.find(_T("stdio"));
if (pos == 0) if (pos == 0)
{ {
#ifdef __LINUX__ #ifdef __LINUX__
m_Src = m_BootCmd; m_Src = m_BootCmd;
m_DebugPort = _T("stdio");
return true; return true;
#else #else
cerr << "Error: reading from stdio is not supported for windows hosts - use pipes" << endl; cerr << "Error: reading from stdio is not supported for windows hosts - use pipes" << endl;
@ -387,6 +386,11 @@ namespace Sysreg_
} }
getDefaultHDDImage(m_HDDImage); getDefaultHDDImage(m_HDDImage);
if (isFileExisting(m_HDDImage))
{
cerr << "Falling back to default hdd image " << m_HDDImage << endl;
return true;
}
return createHDDImage(m_HDDImage); return createHDDImage(m_HDDImage);
} }
/* /*
@ -552,19 +556,20 @@ namespace Sysreg_
} }
cerr << "Opening Data Source:" << m_BootCmd << endl; cerr << "Opening Data Source:" << m_BootCmd << endl;
/*
#ifdef __LINUX__ #ifdef __LINUX__
_tremove(m_PidFile.c_str ()); _tremove(m_PidFile.c_str ());
m_DataSource = new PipeReader(); m_DataSource = new PipeReader();
m_Src = m_BootCmd; m_Src = m_BootCmd;
#else #else
*/
m_DataSource = new NamedPipeReader(); m_DataSource = new NamedPipeReader();
if (!executeBootCmd()) if (!executeBootCmd())
{ {
cerr << "Error: failed to launch emulator with: " << m_BootCmd << endl; cerr << "Error: failed to launch emulator with: " << m_BootCmd << endl;
return false; return false;
} }
#endif //#endif
return true; return true;
} }
@ -659,23 +664,19 @@ namespace Sysreg_
return false; return false;
} }
#endif #endif
#ifndef __LINUX__
OsSupport::delayExecution(1);
#endif
assert(m_DataSource != 0); if (m_DelayRead)
{
cerr << "Delaying read for " << m_DelayRead << " seconds" << endl;
OsSupport::delayExecution(m_DelayRead);
}
if (!m_DataSource->openSource(m_Src)) if (!m_DataSource->openSource(m_Src))
{ {
cerr << "Error: failed to open data source with " << m_Src << endl; cerr << "Error: failed to open data source with " << m_Src << endl;
cleanup(); cleanup();
return false; return false;
} }
if (m_DelayRead)
{
OsSupport::delayExecution(m_DelayRead);
}
#ifdef __LINUX__ #ifdef __LINUX__
/* /*
* For linux systems we can only * For linux systems we can only

View file

@ -157,6 +157,7 @@ protected:
string m_MaxMem; string m_MaxMem;
string m_BootCmd; string m_BootCmd;
string m_Src; string m_Src;
string m_DebugPort;
string m_PidFile; string m_PidFile;
DataSource * m_DataSource; DataSource * m_DataSource;

View file

@ -60,7 +60,7 @@ ROS_EMU_PATH=/usr/bin/qemu
; ;
; Note: set this value if you have problems with timeouts or cutoff debugging data ; Note: set this value if you have problems with timeouts or cutoff debugging data
; ;
ROS_DELAY_READ=4000 ROS_DELAY_READ=4
; ROS_CHECK_POINT ; ROS_CHECK_POINT
; ;