void CSubprocess::ThreadFunc() { TRACE(_T("Reading from process %d\n"),m_idProcess); DWORD dwAvail; DWORD dwExitCode; while (!m_bKillThread && m_pfnContinue(m_pContinuationFuncParam) && ::PeekNamedPipe(m_hrPipe, NULL, 0, 0, &dwAvail, NULL)){ //TRACE(_T("P%d\n"),dwAvail); if(dwAvail){ dwAvail=MIN(dwAvail,80); // Read a maximum of 80 characters at a time DWORD dwRead; char *buf=new char[dwAvail+1]; //TRACE(_T("R%d\n"),dwAvail); if(!::ReadFile(m_hrPipe, buf, dwAvail, &dwRead, NULL)){ TRACE(_T("ReadFile returns false\n")); delete [] buf; break; } buf[dwRead]='\0'; Output(String::CStrToUnicodeStr(buf)); delete [] buf; } else if (!ProcessAlive()) { TRACE(_T("m_bThreadTerminated=%d\n"),m_bThreadTerminated); break; } // Fix for hanging in an endless loop under Windows ME, by Bill Diehls <*****@*****.**> else if (::GetExitCodeProcess(m_hProcess, &dwExitCode) && dwExitCode!=STILL_ACTIVE) { break; } else { CeCosThreadUtils::Sleep(250); } } ::GetExitCodeProcess(m_hProcess, &dwExitCode); m_nExitCode=dwExitCode; #ifdef _DEBUG String str; switch(dwExitCode){ case STILL_ACTIVE: str=_T("still alive"); if(m_bKillThread){ str+=_T(" - requested to stop reading"); } break; case PROCESS_KILL_EXIT_CODE: str=_T("killed"); break; default: str.Format(_T("terminated rc=%d"),dwExitCode); break; } TRACE(_T("Finished reading from process %d (%s)\n"),m_idProcess,(LPCTSTR)str); #endif CloseHandle(m_hrPipe);m_hrPipe=INVALID_HANDLE_VALUE; CloseHandle(m_hwPipe);m_hwPipe=INVALID_HANDLE_VALUE; if(m_bAutoDelete){ m_bThreadTerminated=true; // or else the dtor will block delete this; } }
int main (int argc, char *argv[]) { char psBuffer[BUFFER_SIZE]; char psGnuplotCommandLine[MAX_PATH] = PROGNAME; LPTSTR psCmdLine; BOOL bSuccess; BOOL bPersist = FALSE; int i; #if !defined(_O_BINARY) && defined(O_BINARY) # define _O_BINARY O_BINARY # define _setmode setmode /* this is for BC4.5 ... */ #endif _setmode(fileno(stdout), _O_BINARY); for (i = 1; i < argc; i++) { if (!argv[i]) continue; if (!strcmp(argv[i], "-V") || !strcmp(argv[i], "--version")) { printf("gnuplot %s patchlevel %s\n", gnuplot_version, gnuplot_patchlevel); return 0; } else if ((!stricmp(argv[i], "-noend")) || (!stricmp(argv[i], "/noend")) || (!stricmp(argv[i], "-persist"))) { bPersist = TRUE; } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { printf("Usage: gnuplot [OPTION] [FILE] [-]\n" " -V, --version show gnuplot version\n" " -h, --help show this help\n" " -e \"cmd; cmd; ...\" prepand additional commands\n" " -persist don't close the plot after executing FILE\n" " -noend, /noend like -persist (non-portable Windows-only options)\n" " - allow work in interactive mode after executing FILE\n" "Only on Windows, -persist and - have the same effect.\n" "This is gnuplot %s patchlevel %s\n" "Report bugs to <*****@*****.**>\n", gnuplot_version, gnuplot_patchlevel); return 0; } } /* for(argc) */ /* CRS: create the new command line, passing all of the command * line options to wgnuplot so that it can process them: * first, get the command line, * then move past the name of the program (e.g., 'pgnuplot'), * finally, add what's left of the line onto the gnuplot command line. */ psCmdLine = GetCommandLine(); #ifdef SHOWCMDLINE fprintf(stderr,"CmdLine: %s\n", psCmdLine); fprintf(stderr,"argv[0]: %s\n",argv[0]); #endif /* CRS 30061999: Search for the first unquoted space. This should separate the program name from the arguments. */ psCmdLine = FindUnquotedSpace(psCmdLine); strncat(psGnuplotCommandLine, psCmdLine, sizeof(psGnuplotCommandLine) - strlen(psGnuplotCommandLine)-1); #ifdef SHOWCMDLINE fprintf(stderr,"Arguments: %s\n", psCmdLine); fprintf(stderr,"GnuplotCommandLine: %s\n",psGnuplotCommandLine); #endif /* CRS: if stdin isn't redirected then just launch wgnuplot normally * and exit. */ if (isatty(fileno(stdin))) { if (WinExec(psGnuplotCommandLine, SW_SHOWDEFAULT) > 31) { exit(EXIT_SUCCESS); } fprintf(stderr,"ERROR %u: Couldn't execute: \"%s\"\n", GetLastError(), psGnuplotCommandLine); exit(EXIT_FAILURE); } /* CRS: initialize the STARTUPINFO and call CreateProcess(). */ siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.lpReserved = NULL; siStartInfo.lpReserved2 = NULL; siStartInfo.cbReserved2 = 0; siStartInfo.lpDesktop = NULL; siStartInfo.dwFlags = STARTF_USESHOWWINDOW; siStartInfo.wShowWindow = SW_SHOWMINIMIZED; bSuccess = CreateProcess( NULL, /* pointer to name of executable module */ psGnuplotCommandLine, /* pointer to command line string */ NULL, /* pointer to process security attributes */ NULL, /* pointer to thread security attributes */ FALSE, /* handle inheritance flag */ 0, /* creation flags */ NULL, /* pointer to new environment block */ NULL, /* pointer to current directory name */ &siStartInfo, /* pointer to STARTUPINFO */ &piProcInfo /* pointer to PROCESS_INFORMATION */ ); /* if CreateProcess() failed, print a warning and exit. */ if (! bSuccess) { fprintf(stderr,"ERROR %u: Couldn't execute: \"%s\"\n", GetLastError(), psGnuplotCommandLine); exit(EXIT_FAILURE); } /* CRS: give gnuplot enough time to start (1 sec.) */ if (WaitForInputIdle(piProcInfo.hProcess, 1000)) { fprintf(stderr, "Timeout: gnuplot is not ready\n"); exit(EXIT_FAILURE); } /* CRS: get the HWND of the parent window and text windows */ EnumThreadWindows(piProcInfo.dwThreadId, cbGetTextWindow, 0); if (! hwndParent || ! hwndText) { /* Still no gnuplot window? Problem! */ fprintf(stderr, "Can't find the gnuplot window"); /* CRS: free the process and thread handles */ CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); exit(EXIT_FAILURE); } /* wait for commands on stdin, and pass them on to the wgnuplot text * window */ while (fgets(psBuffer, BUFFER_SIZE, stdin) != NULL) { /* RWH: Check if wgnuplot is still alive */ if (!ProcessAlive(piProcInfo.hProcess)) break; PostString(hwndText, psBuffer); } /* exit gracefully, unless -persist is requested */ if (!bPersist && ProcessAlive(piProcInfo.hProcess)) { PostString(hwndText, "\nexit\n"); } /* CRS: free the process and thread handles */ CloseHandle(piProcInfo.hProcess); CloseHandle(piProcInfo.hThread); return EXIT_SUCCESS; }