7 DWORD WINAPI ThreadProc(LPVOID lpParam){
8 PipeStruct *p=(PipeStruct *) lpParam;
17 void PipeStruct::Open(const char *szProcFile) {
19 HANDLE hStdinRead, hStdinWrite, hStdoutRead, hStdoutWrite;
20 SECURITY_ATTRIBUTES sa;
22 PROCESS_INFORMATION pi;
24 if (szProcFile == NULL) {
25 hInput = GetStdHandle(STD_INPUT_HANDLE);
26 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
27 bConsole = GetConsoleMode(hInput, &dwMode);
30 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
31 sa.bInheritHandle = TRUE;
32 sa.lpSecurityDescriptor = NULL;
33 CreatePipe(&hStdinRead, &hStdinWrite, &sa, 0);
34 CreatePipe(&hStdoutRead, &hStdoutWrite, &sa, 0);
35 si.cb = sizeof(STARTUPINFO);
36 si.lpReserved = si.lpDesktop = si.lpTitle = NULL;
37 si.dwFlags = STARTF_USESTDHANDLES;
39 si.lpReserved2 = NULL;
40 si.hStdInput = hStdinRead;
41 si.hStdOutput = hStdoutWrite;
42 si.hStdError = hStdoutWrite;
43 if(CreateProcess(NULL,
48 DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP,
54 CloseHandle(pi.hThread);
55 CloseHandle(hStdinRead);
56 CloseHandle(hStdoutWrite);
58 hOutput = hStdinWrite;
62 my_fatal("PipeStruct::Open(): %s",my_error());
66 SetConsoleMode(hInput,
67 dwMode & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT));
68 FlushConsoleInputBuffer(hInput);
72 InitializeCriticalSection(&CriticalSection);
73 hEvent=CreateEvent(NULL, // default security
75 FALSE, // not signaled
78 hThread=CreateThread(NULL, // default security
79 0, // default stacksize
80 ThreadProc, // worker function
81 this, // tell worker about ourselves
90 void PipeStruct::Close(void) const {
94 void PipeStruct::Kill(void) const {
99 if(GetExitCodeProcess(hProcess,&lpexit)){
100 if(lpexit==STILL_ACTIVE)
101 //must be java,hammer it down!
102 TerminateProcess(hProcess,lpexit);
104 CloseHandle(hProcess);
107 bool PipeStruct::EOF_(void){ // EOF is defined
109 EnterCriticalSection(&CriticalSection);
111 LeaveCriticalSection(&CriticalSection);
115 void PipeStruct::set_EOF_(void){
116 EnterCriticalSection(&CriticalSection);
118 LeaveCriticalSection(&CriticalSection);
121 bool PipeStruct::Active(void){
123 EnterCriticalSection(&CriticalSection);
124 ret=state&PIPE_ACTIVE;
125 LeaveCriticalSection(&CriticalSection);
129 void PipeStruct::set_Active(void){
130 EnterCriticalSection(&CriticalSection);
132 LeaveCriticalSection(&CriticalSection);
135 int PipeStruct::ReadData(void){
140 fgets(lpReadBuffer,LINE_INPUT_MAX_CHAR,stdin);
141 dwBytes=strlen(lpReadBuffer);
144 lpReadBuffer[0]='\0';
148 // Unfortunately we need to use polling here.
149 // Otherwise Windows returns single bytes if
150 // the engine runs at low priority.
151 // This kills performance.
153 ret=PeekNamedPipe(hInput,
154 NULL, // don't read anything yet
156 NULL, // no we don't read anything!
157 &dwBytes,// now we're talking
158 NULL); // nono we don't read anything
161 lpReadBuffer[0]='\0';
178 lpReadBuffer[0]='\0';
182 lpReadBuffer[dwBytes]='\0';
186 void PipeStruct::ReadInput(void) {
189 BOOL bSetEvent=FALSE;
191 EnterCriticalSection(&CriticalSection);
193 if(ret+nReadEnd>=LINE_INPUT_MAX_CHAR){
194 my_fatal("PipeStruct::ReadInput(): buffer overflow\n");
196 memcpy(lpBuffer+nReadEnd,lpReadBuffer,ret);
199 lpFeedEnd = (char *) memchr(lpBuffer, '\n', nReadEnd);
205 LeaveCriticalSection(&CriticalSection);
206 if(EOF_() || bSetEvent){
211 bool PipeStruct::GetBuffer(char *szLineStr) {
214 EnterCriticalSection(&CriticalSection);
215 if (lpFeedEnd == NULL) {
218 nFeedEnd = lpFeedEnd - lpBuffer;
219 memcpy(szLineStr, lpBuffer, nFeedEnd);
220 if (szLineStr[nFeedEnd - 1] == '\r') {
221 szLineStr[nFeedEnd - 1] = '\0';
223 szLineStr[nFeedEnd] = '\0';
226 nReadEnd -= nFeedEnd;
227 memcpy(lpBuffer, lpBuffer + nFeedEnd, nReadEnd);
228 lpFeedEnd = (char *) memchr(lpBuffer, '\n', nReadEnd);
231 LeaveCriticalSection(&CriticalSection);
235 void PipeStruct::LineInput(char *szLineStr) {
237 if (GetBuffer(szLineStr)) {
240 WaitForSingleObject(hEvent,INFINITE);
245 void PipeStruct::LineOutput(const char *szLineStr) const {
248 char szWriteBuffer[LINE_INPUT_MAX_CHAR];
250 nStrLen = strlen(szLineStr);
251 memcpy(szWriteBuffer, szLineStr, nStrLen);
252 szWriteBuffer[nStrLen] = '\r';
253 szWriteBuffer[nStrLen + 1] = '\n';
254 WriteFile(hOutput, szWriteBuffer, nStrLen + 2, &dwBytes, NULL);
256 printf("%s\n",szLineStr);