4 void PipeStruct::Open(const char *szProcFile) {
6 HANDLE hStdinRead, hStdinWrite, hStdoutRead, hStdoutWrite;
7 SECURITY_ATTRIBUTES sa;
9 PROCESS_INFORMATION pi;
11 if (szProcFile == NULL) {
12 hInput = GetStdHandle(STD_INPUT_HANDLE);
13 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
14 bConsole = GetConsoleMode(hInput, &dwMode);
16 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
17 sa.bInheritHandle = TRUE;
18 sa.lpSecurityDescriptor = NULL;
19 CreatePipe(&hStdinRead, &hStdinWrite, &sa, 0);
20 CreatePipe(&hStdoutRead, &hStdoutWrite, &sa, 0);
21 si.cb = sizeof(STARTUPINFO);
22 si.lpReserved = si.lpDesktop = si.lpTitle = NULL;
23 si.dwFlags = STARTF_USESTDHANDLES;
25 si.lpReserved2 = NULL;
26 si.hStdInput = hStdinRead;
27 si.hStdOutput = hStdoutWrite;
28 si.hStdError = hStdoutWrite;
29 if(!CreateProcess(NULL, (LPSTR) szProcFile, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi)){
30 my_fatal("PipeStruct::Open(): Could not start \"%s\"\n",szProcFile);
33 //CloseHandle(pi.hProcess);//not here,baby,but in pipe.close
34 CloseHandle(pi.hThread);
35 CloseHandle(hStdinRead);
36 CloseHandle(hStdoutWrite);
38 hOutput = hStdinWrite;
42 SetConsoleMode(hInput, dwMode & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT));
43 FlushConsoleInputBuffer(hInput);
50 void PipeStruct::Close(void) const {
55 my_log("POLYGLOT Closing child\n");
56 if(GetExitCodeProcess(hProcess,&lpexit)){
57 if(lpexit==STILL_ACTIVE)
58 my_log("POLYGLOT Process still active after \"quit\" ");
59 //must be java,hammer it down!
60 TerminateProcess(hProcess,lpexit);
62 CloseHandle(hProcess);
65 void PipeStruct::ReadInput(void) {
67 if(!ReadFile(hInput, szBuffer + nReadEnd, LINE_INPUT_MAX_CHAR - nReadEnd, &dwBytes, NULL)){
68 // TODO move this comment to a more suitable place
69 my_log("POLYGLOT *** EOF from Engine or GUI ***\n");
70 exit(EXIT_SUCCESS); // if we are here there should be data!
74 nBytesLeft -= dwBytes;
78 bool PipeStruct::CheckInput(void) {
79 DWORD dwEvents, dwBytes;
80 if (bConsole) { // a tty, or an un-redirected handle
81 GetNumberOfConsoleInputEvents(hInput, &dwEvents);
87 } else { // a handle redirected to a pipe or a file
91 if (PeekNamedPipe(hInput, NULL, 0, NULL, &dwBytes, NULL)) {
93 return nBytesLeft > 0; // a pipe
95 return TRUE; // a file, always TRUE
101 void PipeStruct::LineOutput(const char *szLineStr) const {
104 char szWriteBuffer[LINE_INPUT_MAX_CHAR];
105 nStrLen = strlen(szLineStr);
106 memcpy(szWriteBuffer, szLineStr, nStrLen);
107 szWriteBuffer[nStrLen] = '\r';
108 szWriteBuffer[nStrLen + 1] = '\n';
109 WriteFile(hOutput, szWriteBuffer, nStrLen + 2, &dwBytes, NULL);
114 bool PipeStruct::GetBuffer(char *szLineStr) {
117 lpFeedEnd = (char *) memchr(szBuffer, '\n', nReadEnd);
118 if (lpFeedEnd == NULL) {
121 nFeedEnd = lpFeedEnd - szBuffer;
122 memcpy(szLineStr, szBuffer, nFeedEnd);
123 if (szLineStr[nFeedEnd - 1] == '\r') {
124 szLineStr[nFeedEnd - 1] = '\0';
126 szLineStr[nFeedEnd] = '\0';
129 nReadEnd -= nFeedEnd;
130 memcpy(szBuffer, szBuffer + nFeedEnd, nReadEnd);
135 bool PipeStruct::LineInput(char *szLineStr) {
136 if (GetBuffer(szLineStr)) {
141 if (GetBuffer(szLineStr)) {
144 if (nReadEnd == LINE_INPUT_MAX_CHAR) {
145 memcpy(szLineStr, szBuffer, LINE_INPUT_MAX_CHAR - 1);
146 szLineStr[LINE_INPUT_MAX_CHAR - 1] = '\0';
147 szBuffer[0] = szBuffer[LINE_INPUT_MAX_CHAR - 1];