Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Examples

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 Wed Apr 6 10:22:14 2005 for Gnuplot by doxygen 1.3.8