version 1.4w10UCIb22
[polyglot.git] / pipe.cpp
index 163e591..5d07844 100644 (file)
--- a/pipe.cpp
+++ b/pipe.cpp
@@ -20,6 +20,7 @@ void PipeStruct::Open(const char *szProcFile) {
     SECURITY_ATTRIBUTES sa;
     STARTUPINFO si;
     PROCESS_INFORMATION pi;
+    int fdInput;
     state=0;
     if (szProcFile == NULL) {
         hInput = GetStdHandle(STD_INPUT_HANDLE);
@@ -67,7 +68,16 @@ void PipeStruct::Open(const char *szProcFile) {
                        dwMode & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT));
         FlushConsoleInputBuffer(hInput);
     } 
+    fdInput=_open_osfhandle((intptr_t) hInput,_O_RDONLY);
+    if(fdInput==-1){
+        my_fatal("PipeStruct::Open(): %s",my_error());
+    }
+    fpInput=fdopen(fdInput,"r");
+    if(fpInput==NULL){
+        my_fatal("PipeStruct::Open(): %s",my_error());
+    }
     nReadEnd = 0;
+    lpFeedEnd = NULL;
     InitializeCriticalSection(&CriticalSection);
     hEvent=CreateEvent(NULL,           // default security
                        FALSE,          // auto reset
@@ -131,72 +141,26 @@ void PipeStruct::set_Active(void){
     LeaveCriticalSection(&CriticalSection);
 }
 
-
-
-int PipeStruct::ReadLine(void){
+int PipeStruct::ReadData(void){
     DWORD dwBytes;
-    int ret;
-    int start=0;
-    int start1;    
+    char * ret;
     
-    if(!bPipe){
-        fgets(lpReadBuffer,LINE_INPUT_MAX_CHAR,stdin);
-        start=strlen(lpReadBuffer);
-        if(!start){
-            set_EOF_();
-            lpReadBuffer[0]='\0';
-        }
-        return start;
-    }else{
-        while(TRUE){
-                // Unfortunately we need to use polling here.
-                // Otherwise Windows returns single bytes if
-                // the engine runs at low priority.
-                // This kills performance.
-            while(TRUE){
-                ret=PeekNamedPipe(hInput,
-                                  NULL,    // don't read anything yet
-                                  0,       // no buffer
-                                  NULL,    // no we don't read anything!
-                                  &dwBytes,// now we're talking
-                                  NULL);   // nono we don't read anything
-                if(!ret){
-                    set_EOF_();
-                    lpReadBuffer[0]='\0';
-                    return 0;
-                }
-                if(dwBytes>0){
-                    break;
-                }else{
-                    Idle();
-                }
-                
-            }
-            ret=ReadFile(hInput,
-                         lpReadBuffer+start,
-                         LINE_INPUT_MAX_CHAR-start,
-                         &dwBytes,
-                         NULL);
-            if(!ret){
-                set_EOF_();
-                lpReadBuffer[0]='\0';
-                return 0;
-            }else{
-                start1=start;
-                start+=dwBytes;
-                if (memchr(lpReadBuffer+start1, '\n', dwBytes)){
-                    lpReadBuffer[start]='\0';
-                    return start;
-                }
-            }
-        }
+    ret=fgets(lpReadBuffer,LINE_INPUT_MAX_CHAR,fpInput);
+    dwBytes=strlen(lpReadBuffer);
+    if(!ret){
+        set_EOF_();
+        lpReadBuffer[0]='\0';
+        return 0;
     }
+    lpReadBuffer[dwBytes]='\0';
+    return dwBytes;
 }
 
 void PipeStruct::ReadInput(void) {
   DWORD dwBytes;
   int ret;
-  ret=ReadLine();
+  BOOL bSetEvent=FALSE;
+  ret=ReadData();
   EnterCriticalSection(&CriticalSection);
   if(!EOF_()){
       if(ret+nReadEnd>=LINE_INPUT_MAX_CHAR){
@@ -204,33 +168,23 @@ void PipeStruct::ReadInput(void) {
       }
       memcpy(lpBuffer+nReadEnd,lpReadBuffer,ret);
       nReadEnd += ret;
+      if(!lpFeedEnd){
+          lpFeedEnd = (char *) memchr(lpBuffer, '\n', nReadEnd);
+      }
+      if(lpFeedEnd){
+          bSetEvent=TRUE;
+      }
   }
   LeaveCriticalSection(&CriticalSection);
-  SetEvent(hEvent);
-}
-
-void PipeStruct::LineOutput(const char *szLineStr) const {
-  DWORD dwBytes;
-  int nStrLen;
-  char szWriteBuffer[LINE_INPUT_MAX_CHAR];
-  if(bPipe){
-      nStrLen = strlen(szLineStr);
-      memcpy(szWriteBuffer, szLineStr, nStrLen);
-      szWriteBuffer[nStrLen] = '\r';
-      szWriteBuffer[nStrLen + 1] = '\n';
-      WriteFile(hOutput, szWriteBuffer, nStrLen + 2, &dwBytes, NULL);
-  }else{
-      printf("%s\n",szLineStr);
-      fflush(stdout);
+  if(EOF_() || bSetEvent){
+      SetEvent(hEvent);
   }
 }
 
 bool PipeStruct::GetBuffer(char *szLineStr) {
-  char *lpFeedEnd;
   int nFeedEnd;
   int ret;
   EnterCriticalSection(&CriticalSection);
-  lpFeedEnd = (char *) memchr(lpBuffer, '\n', nReadEnd);
   if (lpFeedEnd == NULL) {
     ret=FALSE;
   } else {
@@ -244,6 +198,7 @@ bool PipeStruct::GetBuffer(char *szLineStr) {
     nFeedEnd ++;
     nReadEnd -= nFeedEnd;
     memcpy(lpBuffer, lpBuffer + nFeedEnd, nReadEnd);
+    lpFeedEnd = (char *) memchr(lpBuffer, '\n', nReadEnd);
     ret=TRUE;
   }
   LeaveCriticalSection(&CriticalSection);
@@ -259,4 +214,20 @@ void PipeStruct::LineInput(char *szLineStr) {
         }
     }
 }
+
+void PipeStruct::LineOutput(const char *szLineStr) const {
+  DWORD dwBytes;
+  int nStrLen;
+  char szWriteBuffer[LINE_INPUT_MAX_CHAR];
+  if(bPipe){
+      nStrLen = strlen(szLineStr);
+      memcpy(szWriteBuffer, szLineStr, nStrLen);
+      szWriteBuffer[nStrLen] = '\r';
+      szWriteBuffer[nStrLen + 1] = '\n';
+      WriteFile(hOutput, szWriteBuffer, nStrLen + 2, &dwBytes, NULL);
+  }else{
+      printf("%s\n",szLineStr);
+      fflush(stdout);
+  }
+}
 #endif