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

View file

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

View file

@ -157,6 +157,7 @@ protected:
string m_MaxMem;
string m_BootCmd;
string m_Src;
string m_DebugPort;
string m_PidFile;
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
;
ROS_DELAY_READ=4000
ROS_DELAY_READ=4
; ROS_CHECK_POINT
;