mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 08:15:41 +00:00
- 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:
parent
a04c49f61c
commit
a1de0509ed
5 changed files with 135 additions and 94 deletions
|
@ -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_
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
;
|
;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue