gnuplot_win32.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #ifdef GNUPLOT_ONLY_INCLUDES
00003 
00004 #include <io.h>
00005 #include <fcntl.h>
00006 #include <windows.h> 
00007 #include <malloc.h> // alloca()
00008 
00009 
00010 #else
00011 
00012 // the next is "stolen" from the popen implementation of Python
00013 // my own try to write this didn't work, maybe the docs of MSDN
00014 // are not specific enough
00015 
00016 static FILE* 
00017 win32_error(const char*, void *){
00018     return NULL;
00019 }
00020 
00021 static int
00022 _PyPopenCreateProcess(char *cmdstring,
00023                       HANDLE hStdin,
00024                       HANDLE hStdout,
00025                       HANDLE hStderr)
00026 {
00027     PROCESS_INFORMATION piProcInfo;
00028     STARTUPINFO siStartInfo;
00029     char *s1,*s2, *s3 = " /c ";
00030     const char *szConsoleSpawn = "w9xpopen.exe \"";
00031     int i;
00032     int x;
00033  
00034     if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
00035         s1 = (char *)_alloca(i);
00036         if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
00037             return x;
00038         if (GetVersion() < 0x80000000) {
00039             /*
00040              * NT/2000
00041              */
00042             x = i + strlen(s3) + strlen(cmdstring) + 1;
00043             s2 = (char *)_alloca(x);
00044             ZeroMemory(s2, x);
00045             sprintf(s2, "%s%s%s", s1, s3, cmdstring);
00046         }
00047         else {
00048             /*
00049              * Oh gag, we're on Win9x. Use the workaround listed in
00050              * KB: Q150956
00051              */
00052             char modulepath[256];
00053             GetModuleFileName(NULL, modulepath, sizeof(modulepath));
00054             for (i = x = 0; modulepath[i]; i++)
00055                 if (modulepath[i] == '\\')
00056                     x = i+1;
00057             modulepath[x] = '\0';
00058             x = i + strlen(s3) + strlen(cmdstring) + 1 +
00059                 strlen(modulepath) + 
00060                 strlen(szConsoleSpawn) + 1;
00061             s2 = (char *)_alloca(x);
00062             ZeroMemory(s2, x);
00063             sprintf(
00064                 s2,
00065                 "%s%s%s%s%s\"",
00066                 modulepath,
00067                 szConsoleSpawn,
00068                 s1,
00069                 s3,
00070                 cmdstring);
00071         }
00072     }
00073 
00074     /* Could be an else here to try cmd.exe / command.com in the path
00075        Now we'll just error out.. */
00076     else
00077         return -1;
00078   
00079     ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
00080     siStartInfo.cb = sizeof(STARTUPINFO);
00081     siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
00082     siStartInfo.hStdInput = hStdin;
00083     siStartInfo.hStdOutput = hStdout;
00084     siStartInfo.hStdError = hStderr;
00085     siStartInfo.wShowWindow = SW_HIDE;
00086 
00087     if (CreateProcess(NULL,
00088                       s2,
00089                       NULL,
00090                       NULL,
00091                       TRUE,
00092                       CREATE_NEW_CONSOLE,
00093                       NULL,
00094                       NULL,
00095                       &siStartInfo,
00096                       &piProcInfo) ) {
00097         /* Close the handles now so anyone waiting is woken. */
00098         CloseHandle(piProcInfo.hProcess);
00099         CloseHandle(piProcInfo.hThread);
00100         return TRUE;
00101     }
00102     return FALSE;
00103 }
00104 
00105 
00106 static FILE* 
00107 OpenPipe(char *cmdstring, int mode)
00108 {
00109     HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
00110         hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
00111         hChildStderrRdDup; /* hChildStdoutWrDup; */
00112           
00113     SECURITY_ATTRIBUTES saAttr;
00114     BOOL fSuccess;
00115     int fd1, fd2, fd3;
00116     FILE *f1, *f2, *f3;
00117 
00118     saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
00119     saAttr.bInheritHandle = TRUE;
00120     saAttr.lpSecurityDescriptor = NULL;
00121 
00122     if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
00123         return win32_error("CreatePipe", NULL);
00124 
00125     /* Create new output read handle and the input write handle. Set
00126      * the inheritance properties to FALSE. Otherwise, the child inherits
00127      * the these handles; resulting in non-closeable handles to the pipes
00128      * being created. */
00129     fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
00130                                GetCurrentProcess(), &hChildStdinWrDup, 0,
00131                                FALSE,
00132                                DUPLICATE_SAME_ACCESS);
00133     if (!fSuccess)
00134         return win32_error("DuplicateHandle", NULL);
00135 
00136     /* Close the inheritable version of ChildStdin
00137        that we're using. */
00138     CloseHandle(hChildStdinWr);
00139 
00140     if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
00141         return win32_error("CreatePipe", NULL);
00142 
00143     fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
00144                                GetCurrentProcess(), &hChildStdoutRdDup, 0,
00145                                FALSE,
00146                                DUPLICATE_SAME_ACCESS);
00147     if (!fSuccess)
00148         return win32_error("DuplicateHandle", NULL);
00149 
00150     /* Close the inheritable version of ChildStdout
00151        that we're using. */
00152     CloseHandle(hChildStdoutRd);
00153 
00154     if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
00155         return win32_error("CreatePipe", NULL);
00156     fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStderrRd,
00157                                GetCurrentProcess(), &hChildStderrRdDup, 0,
00158                                FALSE,
00159                                DUPLICATE_SAME_ACCESS);
00160     if (!fSuccess)
00161         return win32_error("DuplicateHandle", NULL);
00162     /* Close the inheritable version of ChildStdErr that we're using. */
00163     CloseHandle(hChildStderrRd);
00164                           
00165     /* Case for writing to child Stdin in text mode. */
00166     fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
00167     f1 = _fdopen(fd1, "w");
00168     /* We don't care about these pipes anymore, so close them. */
00169     CloseHandle(hChildStdoutRdDup);
00170     CloseHandle(hChildStderrRdDup);
00171 
00172 /*
00173 // Case for writing to child Stdin in binary mode.
00174 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
00175 f1 = _fdopen(fd1, "wb");
00176 // We don't care about these pipes anymore, so close them.
00177 CloseHandle(hChildStdoutRdDup);
00178 CloseHandle(hChildStderrRdDup);
00179 */      
00180         
00181     if (!_PyPopenCreateProcess(cmdstring,
00182                                hChildStdinRd,
00183                                hChildStdoutWr,
00184                                hChildStderrWr))
00185         return win32_error("CreateProcess", NULL);
00186 
00187     /* Child is launched. Close the parents copy of those pipe
00188      * handles that only the child should have open.  You need to
00189      * make sure that no handles to the write end of the output pipe
00190      * are maintained in this process or else the pipe will not close
00191      * when the child process exits and the ReadFile will hang. */
00192 
00193     if (!CloseHandle(hChildStdinRd))
00194         return win32_error("CloseHandle", NULL);
00195           
00196     if (!CloseHandle(hChildStdoutWr))
00197         return win32_error("CloseHandle", NULL);
00198  
00199     if (!CloseHandle(hChildStderrWr))
00200         return win32_error("CloseHandle", NULL);
00201 
00202     return f1;
00203 }
00204 
00205 static FILE* OpenGnuplot(void){
00206     return OpenPipe("g:\\gp373w32\\pgnuplot.exe",_O_WRONLY | _O_TEXT);
00207 }
00208 static void CloseGnuplot(FILE* pipe){
00209     fclose(pipe);
00210 }
00211 #endif

Generated on Tue Apr 4 19:05:03 2006 for Robotsystem from Robot Group Leipzig by  doxygen 1.4.5