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;
25 if (szProcFile == NULL) {
26 hInput = GetStdHandle(STD_INPUT_HANDLE);
27 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
28 bConsole = GetConsoleMode(hInput, &dwMode);
31 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
32 sa.bInheritHandle = TRUE;
33 sa.lpSecurityDescriptor = NULL;
34 CreatePipe(&hStdinRead, &hStdinWrite, &sa, 0);
35 CreatePipe(&hStdoutRead, &hStdoutWrite, &sa, 0);
36 si.cb = sizeof(STARTUPINFO);
37 si.lpReserved = si.lpDesktop = si.lpTitle = NULL;
38 si.dwFlags = STARTF_USESTDHANDLES;
40 si.lpReserved2 = NULL;
41 si.hStdInput = hStdinRead;
42 si.hStdOutput = hStdoutWrite;
43 si.hStdError = hStdoutWrite;
44 if(CreateProcess(NULL,
49 DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP,
55 CloseHandle(pi.hThread);
56 CloseHandle(hStdinRead);
57 CloseHandle(hStdoutWrite);
59 hOutput = hStdinWrite;
63 my_fatal("PipeStruct::Open(): %s",my_error());
67 SetConsoleMode(hInput,
68 dwMode & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT));
69 FlushConsoleInputBuffer(hInput);
71 fdInput=_open_osfhandle((intptr_t) hInput,_O_RDONLY);
73 my_fatal("PipeStruct::Open(): %s",my_error());
75 fpInput=fdopen(fdInput,"r");
77 my_fatal("PipeStruct::Open(): %s",my_error());
81 InitializeCriticalSection(&CriticalSection);
82 hEvent=CreateEvent(NULL, // default security
84 FALSE, // not signaled
87 hThread=CreateThread(NULL, // default security
88 0, // default stacksize
89 ThreadProc, // worker function
90 this, // tell worker about ourselves
99 void PipeStruct::Close(void) const {
100 CloseHandle(hOutput);
103 void PipeStruct::Kill(void) const {
105 CloseHandle(hOutput);
108 if(GetExitCodeProcess(hProcess,&lpexit)){
109 if(lpexit==STILL_ACTIVE)
110 //must be java,hammer it down!
111 TerminateProcess(hProcess,lpexit);
113 CloseHandle(hProcess);
116 bool PipeStruct::EOF_(void){ // EOF is defined
118 EnterCriticalSection(&CriticalSection);
120 LeaveCriticalSection(&CriticalSection);
124 void PipeStruct::set_EOF_(void){
125 EnterCriticalSection(&CriticalSection);
127 LeaveCriticalSection(&CriticalSection);
130 bool PipeStruct::Active(void){
132 EnterCriticalSection(&CriticalSection);
133 ret=state&PIPE_ACTIVE;
134 LeaveCriticalSection(&CriticalSection);
138 void PipeStruct::set_Active(void){
139 EnterCriticalSection(&CriticalSection);
141 LeaveCriticalSection(&CriticalSection);
144 int PipeStruct::ReadData(void){
148 ret=fgets(lpReadBuffer,LINE_INPUT_MAX_CHAR,fpInput);
149 dwBytes=strlen(lpReadBuffer);
152 lpReadBuffer[0]='\0';
155 lpReadBuffer[dwBytes]='\0';
159 void PipeStruct::ReadInput(void) {
162 BOOL bSetEvent=FALSE;
164 EnterCriticalSection(&CriticalSection);
166 if(ret+nReadEnd>=LINE_INPUT_MAX_CHAR){
167 my_fatal("PipeStruct::ReadInput(): buffer overflow\n");
169 memcpy(lpBuffer+nReadEnd,lpReadBuffer,ret);
172 lpFeedEnd = (char *) memchr(lpBuffer, '\n', nReadEnd);
178 LeaveCriticalSection(&CriticalSection);
179 if(EOF_() || bSetEvent){
184 bool PipeStruct::GetBuffer(char *szLineStr) {
187 EnterCriticalSection(&CriticalSection);
188 if (lpFeedEnd == NULL) {
191 nFeedEnd = lpFeedEnd - lpBuffer;
192 memcpy(szLineStr, lpBuffer, nFeedEnd);
193 if (szLineStr[nFeedEnd - 1] == '\r') {
194 szLineStr[nFeedEnd - 1] = '\0';
196 szLineStr[nFeedEnd] = '\0';
199 nReadEnd -= nFeedEnd;
200 memcpy(lpBuffer, lpBuffer + nFeedEnd, nReadEnd);
201 lpFeedEnd = (char *) memchr(lpBuffer, '\n', nReadEnd);
204 LeaveCriticalSection(&CriticalSection);
208 void PipeStruct::LineInput(char *szLineStr) {
210 if (GetBuffer(szLineStr)) {
213 WaitForSingleObject(hEvent,INFINITE);
218 void PipeStruct::LineOutput(const char *szLineStr) const {
221 char szWriteBuffer[LINE_INPUT_MAX_CHAR];
223 nStrLen = strlen(szLineStr);
224 memcpy(szWriteBuffer, szLineStr, nStrLen);
225 szWriteBuffer[nStrLen] = '\r';
226 szWriteBuffer[nStrLen + 1] = '\n';
227 WriteFile(hOutput, szWriteBuffer, nStrLen + 2, &dwBytes, NULL);
229 printf("%s\n",szLineStr);