// functions
-DWORD WINAPI ThreadProc(LPVOID lpParam){
+DWORD WINAPI ThreadProc(LPVOID lpParam){
PipeStruct *p=(PipeStruct *) lpParam;
- while(!p->EOF_()){
- p->ReadInput();
+ while(!p->EOF_input()){
+ if(p->nReadEnd<LINE_INPUT_MAX_CHAR-1){
+ p->ReadInput();
+ }else{
+ // wait until there is room in buffer
+ Sleep(10);
+ }
}
return 0;
}
void PipeStruct::Open(const char *szProcFile) {
- DWORD dwMode;
+ DWORD dwMode, dwThreadId;
HANDLE hStdinRead, hStdinWrite, hStdoutRead, hStdoutWrite;
SECURITY_ATTRIBUTES sa;
STARTUPINFO si;
dwMode & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT));
FlushConsoleInputBuffer(hInput);
}
- fdInput=_open_osfhandle((intptr_t) hInput,_O_RDONLY);
+ fdInput=_open_osfhandle((long) hInput,_O_RDONLY);
if(fdInput==-1){
my_fatal("PipeStruct::Open(): %s",my_error());
}
FALSE, // not signaled
NULL // nameless
);
+ if(!hEvent){
+ my_fatal("PipeStruct::Open(): %s",my_error());
+ }
hThread=CreateThread(NULL, // default security
0, // default stacksize
ThreadProc, // worker function
this, // tell worker about ourselves
0, // run immediately
- NULL // nameless
+ &dwThreadId // dropped, but needed for the call to work in Win9x
);
-
+ if(!hThread){
+ my_fatal("PipeStruct::Open(): %s",my_error());
+ }
set_Active();
}
CloseHandle(hProcess);
}
-bool PipeStruct::EOF_(void){ // EOF is defined
+bool PipeStruct::EOF_input(void){ // EOF is defined
int ret;
EnterCriticalSection(&CriticalSection);
ret=state&PIPE_EOF;
return ret;
}
-void PipeStruct::set_EOF_(void){
+void PipeStruct::set_EOF_input(void){
EnterCriticalSection(&CriticalSection);
state|=PIPE_EOF;
LeaveCriticalSection(&CriticalSection);
int PipeStruct::ReadData(void){
DWORD dwBytes;
char * ret;
-
- ret=fgets(lpReadBuffer,LINE_INPUT_MAX_CHAR,fpInput);
- dwBytes=strlen(lpReadBuffer);
+ // No protection. Access to nReadEnd is atomic.
+ // It is not a problem that nReadEnd becomes smaller after the call.
+ // This just means we have read less than we could have.
+ ret=fgets(lpReadBuffer,LINE_INPUT_MAX_CHAR-nReadEnd,fpInput);
if(!ret){
- set_EOF_();
+ set_EOF_input();
lpReadBuffer[0]='\0';
return 0;
}
+ dwBytes=strlen(lpReadBuffer);
lpReadBuffer[dwBytes]='\0';
return dwBytes;
}
DWORD dwBytes;
int ret;
BOOL bSetEvent=FALSE;
+ // ReadData is outside the critical section otherwise everything
+ // would block during the blocking read
ret=ReadData();
EnterCriticalSection(&CriticalSection);
- if(!EOF_()){
+ if(!EOF_input()){
if(ret+nReadEnd>=LINE_INPUT_MAX_CHAR){
- my_fatal("PipeStruct::ReadInput(): buffer overflow\n");
+ my_fatal("PipeStruct::ReadInput(): Internal error: buffer overflow\n");
}
- memcpy(lpBuffer+nReadEnd,lpReadBuffer,ret);
+ memcpy(lpBuffer+nReadEnd,lpReadBuffer,ret+1);
nReadEnd += ret;
if(!lpFeedEnd){
lpFeedEnd = (char *) memchr(lpBuffer, '\n', nReadEnd);
}
if(lpFeedEnd){
bSetEvent=TRUE;
+ }else if(nReadEnd>=LINE_INPUT_MAX_CHAR-1){
+ my_fatal("PipeStruct::ReadInput(): LINE_INPUT_MAX_CHAR is equal to %d which is too small to contain a full line of engine output or GUI input.\n",LINE_INPUT_MAX_CHAR);
}
}
LeaveCriticalSection(&CriticalSection);
- if(EOF_() || bSetEvent){
+ if(EOF_input() || bSetEvent){
SetEvent(hEvent);
}
}
+bool PipeStruct::EOF_(void){
+ int ret;
+ EnterCriticalSection(&CriticalSection);
+ if(lpFeedEnd != NULL){
+ ret=FALSE;
+ }else if(EOF_input()){
+ ret=TRUE;
+ }else{
+ ret=FALSE;
+ }
+ LeaveCriticalSection(&CriticalSection);
+ return ret;
+}
+
bool PipeStruct::GetBuffer(char *szLineStr) {
int nFeedEnd;
int ret;
return ret;
}
+
+
void PipeStruct::LineInput(char *szLineStr) {
- while(!EOF_()){
+ while(!EOF_()){
if (GetBuffer(szLineStr)) {
break;
}else{