| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911 | 
							- /*=========================================================================
 
-   Program:   CMake - Cross-Platform Makefile Generator
 
-   Module:    $RCSfile$
 
-   Language:  C++
 
-   Date:      $Date$
 
-   Version:   $Revision$
 
-   Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
 
-   See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
 
-      This software is distributed WITHOUT ANY WARRANTY; without even 
 
-      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
 
-      PURPOSE.  See the above copyright notices for more information.
 
- =========================================================================*/
 
- #include "cmWin32ProcessExecution.h"
 
- #include "cmSystemTools.h"   
 
- #include <malloc.h>
 
- #include <io.h>
 
- #include <fcntl.h>
 
- #include <sys/stat.h>
 
- #include <windows.h>
 
- #if defined(__BORLANDC__)
 
- #  define STRICMP stricmp
 
- #  define TO_INTPTR(x) ((long)(x))
 
- #else // Visual studio
 
- #  if ( _MSC_VER >= 1300 )
 
- #    include <stddef.h>
 
- #    define TO_INTPTR(x) ((intptr_t)(x))
 
- #  else // Visual Studio 6
 
- #    define TO_INTPTR(x) ((long)(x))
 
- #  endif // Visual studio .NET
 
- #  define STRICMP _stricmp
 
- #endif // Borland
 
- #define POPEN_1 1
 
- #define POPEN_2 2
 
- #define POPEN_3 3
 
- #define POPEN_4 4
 
- #define cmMAX(x,y) (((x)<(y))?(y):(x))
 
- void DisplayErrorMessage()
 
- {
 
-   LPVOID lpMsgBuf;
 
-   FormatMessage( 
 
-     FORMAT_MESSAGE_ALLOCATE_BUFFER | 
 
-     FORMAT_MESSAGE_FROM_SYSTEM | 
 
-     FORMAT_MESSAGE_IGNORE_INSERTS,
 
-     NULL,
 
-     GetLastError(),
 
-     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
 
-     (LPTSTR) &lpMsgBuf,
 
-     0,
 
-     NULL 
 
-     );
 
-   // Process any inserts in lpMsgBuf.
 
-   // ... 
 
-   // Display the string.
 
-   MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
 
-   // Free the buffer.
 
-   LocalFree( lpMsgBuf );
 
- }
 
-  
 
- // Code from a Borland web site with the following explaination : 
 
- /* In this article, I will explain how to spawn a console application
 
-  * and redirect its standard input/output using anonymous pipes. An
 
-  * anonymous pipe is a pipe that goes only in one direction (read
 
-  * pipe, write pipe, etc.). Maybe you are asking, "why would I ever
 
-  * need to do this sort of thing?" One example would be a Windows
 
-  * telnet server, where you spawn a shell and listen on a port and
 
-  * send and receive data between the shell and the socket
 
-  * client. (Windows does not really have a built-in remote
 
-  * shell). First, we should talk about pipes. A pipe in Windows is
 
-  * simply a method of communication, often between process. The SDK
 
-  * defines a pipe as "a communication conduit with two ends;
 
-  a process
 
-  * with a handle to one end can communicate with a process having a
 
-  * handle to the other end." In our case, we are using "anonymous"
 
-  * pipes, one-way pipes that "transfer data between a parent process
 
-  * and a child process or between two child processes of the same
 
-  * parent process." It's easiest to imagine a pipe as its namesake. An
 
-  * actual pipe running between processes that can carry data. We are
 
-  * using anonymous pipes because the console app we are spawning is a
 
-  * child process. We use the CreatePipe function which will create an
 
-  * anonymous pipe and return a read handle and a write handle. We will
 
-  * create two pipes, on for stdin and one for stdout. We will then
 
-  * monitor the read end of the stdout pipe to check for display on our
 
-  * child process. Every time there is something availabe for reading,
 
-  * we will display it in our app. Consequently, we check for input in
 
-  * our app and send it off to the write end of the stdin pipe. */ 
 
- inline bool IsWinNT() 
 
- //check if we're running NT 
 
- {
 
-   OSVERSIONINFO osv;
 
-   osv.dwOSVersionInfoSize = sizeof(osv);
 
-   GetVersionEx(&osv);
 
-   return (osv.dwPlatformId == VER_PLATFORM_WIN32_NT); 
 
- }
 
- //--------------------------------------------------------------------------- 
 
- bool cmWin32ProcessExecution::BorlandRunCommand(
 
-   const char* command, const char* dir, 
 
-   std::string& output, int& retVal, bool verbose, int /* timeout */, 
 
-   bool hideWindows) 
 
- {
 
-   //verbose = true;
 
-   //std::cerr << std::endl 
 
-   //        << "WindowsRunCommand(" << command << ")" << std::endl 
 
-   //        << std::flush;
 
-   const int BUFFER_SIZE = 4096;
 
-   char buf[BUFFER_SIZE];
 
-  
 
- //i/o buffer 
 
-   STARTUPINFO si;
 
-   SECURITY_ATTRIBUTES sa;
 
-   SECURITY_DESCRIPTOR sd;
 
-  
 
- //security information for pipes 
 
-   PROCESS_INFORMATION pi;
 
-   HANDLE newstdin,newstdout,read_stdout,write_stdin;
 
-  
 
- //pipe handles 
 
-   if (IsWinNT()) 
 
- //initialize security descriptor (Windows NT) 
 
-     {
 
-     InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
 
-     SetSecurityDescriptorDacl(&sd, true, NULL, false);
 
-     sa.lpSecurityDescriptor = &sd;
 
-  
 
-     }
 
-   else sa.lpSecurityDescriptor = NULL;
 
-   sa.nLength = sizeof(SECURITY_ATTRIBUTES);
 
-   sa.bInheritHandle = true;
 
-  
 
- //allow inheritable handles 
 
-   if (!CreatePipe(&newstdin,&write_stdin,&sa,0)) 
 
- //create stdin pipe 
 
-     {
 
-     std::cerr << "CreatePipe" << std::endl;
 
-     return false;
 
-  
 
-     }
 
-   if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) 
 
- //create stdout pipe 
 
-     {
 
-     std::cerr << "CreatePipe" << std::endl;
 
-     CloseHandle(newstdin);
 
-     CloseHandle(write_stdin);
 
-     return false;
 
-  
 
-     }
 
-   GetStartupInfo(&si);
 
-  
 
- //set startupinfo for the spawned process 
 
-   /* The dwFlags member tells CreateProcess how to make the
 
-    * process. STARTF_USESTDHANDLES validates the hStd*
 
-    * members. STARTF_USESHOWWINDOW validates the wShowWindow
 
-    * member. */ 
 
-   
 
-   si.cb = sizeof(STARTUPINFO);
 
-   si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
 
-   si.hStdOutput = newstdout;
 
-   si.hStdError = newstdout;
 
-   si.wShowWindow = SW_SHOWDEFAULT;
 
-   if(hideWindows)
 
-     {
 
-     si.wShowWindow = SW_HIDE;
 
-     }
 
-  
 
- //set the new handles for the child process si.hStdInput = newstdin;
 
-   char* commandAndArgs = strcpy(new char[strlen(command)+1], command);
 
-   if (!CreateProcess(NULL,commandAndArgs,NULL,NULL,TRUE,
 
-                      0, // CREATE_NEW_CONSOLE, 
 
-                      NULL,dir,&si,&pi)) 
 
-     {
 
-     std::cerr << "CreateProcess failed " << commandAndArgs << std::endl;
 
-     CloseHandle(newstdin);
 
-     CloseHandle(newstdout);
 
-     CloseHandle(read_stdout);
 
-     CloseHandle(write_stdin);
 
-     delete [] commandAndArgs;
 
-     return false;
 
-  
 
-     }
 
-   delete [] commandAndArgs;
 
-   unsigned long exit=0;
 
-  
 
- //process exit code unsigned 
 
-   unsigned long bread;
 
-  
 
- //bytes read unsigned 
 
-   unsigned long avail;
 
-  
 
- //bytes available 
 
-   memset(buf, 0, sizeof(buf));
 
-   for(;;) 
 
- //main program loop 
 
-     {
 
-     Sleep(10);
 
- //check to see if there is any data to read from stdout 
 
-     //std::cout << "Peek for data..." << std::endl;
 
-     PeekNamedPipe(read_stdout,buf,1023,&bread,&avail,NULL);
 
-     if (bread != 0) 
 
-       {
 
-       memset(buf, 0, sizeof(buf));
 
-       if (avail > 1023) 
 
-         {
 
-         while (bread >= 1023) 
 
-           {
 
-           //std::cout << "Read data..." << std::endl;
 
-           ReadFile(read_stdout,buf,1023,&bread,NULL);
 
-  
 
-           //read the stdout pipe 
 
-           memset(buf, 0, sizeof(buf));
 
-           output += buf;
 
-           if (verbose)
 
-             {
 
-             cmSystemTools::Stdout(buf);
 
-             }
 
-           }
 
-         }
 
-       else 
 
-         {
 
-         ReadFile(read_stdout,buf,1023,&bread,NULL);
 
-         output += buf;
 
-         if(verbose) 
 
-           {
 
-           cmSystemTools::Stdout(buf);
 
-           }
 
-  
 
-         }
 
-  
 
-       }
 
-  
 
-     //std::cout << "Check for process..." << std::endl;
 
-     GetExitCodeProcess(pi.hProcess,&exit);
 
-  
 
- //while the process is running 
 
-     if (exit != STILL_ACTIVE) break;
 
-  
 
-     }
 
-   WaitForSingleObject(pi.hProcess, INFINITE);
 
-   GetExitCodeProcess(pi.hProcess,&exit);
 
-   CloseHandle(pi.hThread);
 
-   CloseHandle(pi.hProcess);
 
-   CloseHandle(newstdin);
 
-  
 
- //clean stuff up 
 
-   CloseHandle(newstdout);
 
-   CloseHandle(read_stdout);
 
-   CloseHandle(write_stdin);
 
-   retVal = exit;
 
-   return true;
 
-  
 
- }
 
- bool cmWin32ProcessExecution::StartProcess(
 
-   const char* cmd, const char* path, bool verbose)
 
- {
 
-   this->Initialize();
 
-   this->Verbose = verbose;
 
-   return this->PrivateOpen(cmd, path, _O_RDONLY | _O_TEXT, POPEN_3);
 
- }
 
- bool cmWin32ProcessExecution::Wait(int timeout)
 
- {
 
-   return this->PrivateClose(timeout);
 
- }
 
- /*
 
-  * Internal dictionary mapping popen* file pointers to process handles,
 
-  * for use when retrieving the process exit code.  See _PyPclose() below
 
-  * for more information on this dictionary's use.
 
-  */
 
- static void *_PyPopenProcs = NULL;
 
- static BOOL RealPopenCreateProcess(const char *cmdstring,
 
-                                    const char *path, 
 
-                                    const char *szConsoleSpawn,
 
-                                    HANDLE hStdin,
 
-                                    HANDLE hStdout,
 
-                                    HANDLE hStderr,
 
-                                    HANDLE *hProcess,
 
-                                    bool hideWindows,
 
-                                    std::string& output)
 
- {
 
-   PROCESS_INFORMATION piProcInfo;
 
-   STARTUPINFO siStartInfo;
 
-   char *s1=0,*s2=0, *s3 = " /c ";
 
-   int i = GetEnvironmentVariable("COMSPEC",NULL,0);
 
-   if (i)
 
-     {
 
-     char *comshell;
 
-     s1 = (char *)malloc(i);
 
-     int x = GetEnvironmentVariable("COMSPEC", s1, i);
 
-     if (!x)
 
-       {
 
-       free(s1);
 
-       return x;
 
-       }
 
-     /* Explicitly check if we are using COMMAND.COM.  If we are
 
-      * then use the w9xpopen hack.
 
-      */
 
-     comshell = s1 + x;
 
-     while (comshell >= s1 && *comshell != '\\')
 
-       --comshell;
 
-     ++comshell;
 
-     if (GetVersion() < 0x80000000 &&
 
-         STRICMP(comshell, "command.com") != 0) 
 
-       {
 
-       /* NT/2000 and not using command.com. */
 
-       x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1;
 
-       s2 = (char *)malloc(x);
 
-       ZeroMemory(s2, x);
 
-       //sprintf(s2, "%s%s%s", s1, s3, cmdstring);
 
-       sprintf(s2, "%s", cmdstring);
 
-       }
 
-     else 
 
-       {
 
-       /*
 
-        * Oh gag, we're on Win9x or using COMMAND.COM. Use
 
-        * the workaround listed in KB: Q150956
 
-        */
 
-       char modulepath[_MAX_PATH];
 
-       struct stat statinfo;
 
-       GetModuleFileName(NULL, modulepath, sizeof(modulepath));
 
-       for (i = x = 0; modulepath[i]; i++)
 
-         if (modulepath[i] == '\\')
 
-           x = i+1;
 
-       modulepath[x] = '\0';
 
-       /* Create the full-name to w9xpopen, so we can test it exists */
 
-       strncat(modulepath, 
 
-               szConsoleSpawn, 
 
-               (sizeof(modulepath)/sizeof(modulepath[0]))
 
-               -strlen(modulepath));
 
-       if (stat(modulepath, &statinfo) != 0) 
 
-         {
 
-           /* Eeek - file-not-found - possibly an embedding 
 
-              situation - see if we can locate it in sys.prefix 
 
-           */
 
-         strncpy(modulepath, 
 
-                 ".", 
 
-                 sizeof(modulepath)/sizeof(modulepath[0]));
 
-         if (modulepath[strlen(modulepath)-1] != '\\')
 
-           strcat(modulepath, "\\");
 
-         strncat(modulepath, 
 
-                 szConsoleSpawn, 
 
-                 (sizeof(modulepath)/sizeof(modulepath[0]))
 
-                 -strlen(modulepath));
 
-         /* No where else to look - raise an easily identifiable
 
-            error, rather than leaving Windows to report
 
-            "file not found" - as the user is probably blissfully
 
-            unaware this shim EXE is used, and it will confuse them.
 
-            (well, it confused me for a while ;-)
 
-         */
 
-         if (stat(modulepath, &statinfo) != 0) 
 
-           {
 
-           std::cout 
 
-             << "Can not locate '" << modulepath
 
-             << "' which is needed "
 
-             "for popen to work with your shell "
 
-             "or platform." << std::endl;    
 
-           free(s1);
 
-           free(s2);
 
-           return FALSE;
 
-           }
 
-         }
 
-       x = i + (int)strlen(s3) + (int)strlen(cmdstring) + 1 +
 
-         (int)strlen(modulepath) + 
 
-         (int)strlen(szConsoleSpawn) + 1;
 
-       if(s2)
 
-         {
 
-         free(s2);
 
-         }
 
-       s2 = (char *)malloc(x);
 
-       ZeroMemory(s2, x);
 
-       sprintf(
 
-         s2,
 
-         "%s %s%s%s",
 
-         modulepath,
 
-         s1,
 
-         s3,
 
-         cmdstring);
 
-       sprintf(
 
-         s2,
 
-         "%s %s",
 
-         modulepath,
 
-         cmdstring);
 
-       }
 
-     }
 
-   /* Could be an else here to try cmd.exe / command.com in the path
 
-      Now we'll just error out.. */
 
-   else 
 
-     {
 
-     std::cout << "Cannot locate a COMSPEC environment variable to "
 
-               << "use as the shell" << std::endl; 
 
-     free(s2);
 
-     free(s1);
 
-     return FALSE;
 
-     }
 
-   
 
-   ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
 
-   siStartInfo.cb = sizeof(STARTUPINFO);
 
-   siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
 
-   siStartInfo.hStdInput = hStdin;
 
-   siStartInfo.hStdOutput = hStdout;
 
-   siStartInfo.hStdError = hStderr;
 
-   siStartInfo.wShowWindow = SW_SHOWDEFAULT; 
 
-   if(hideWindows)
 
-     {
 
-     siStartInfo.wShowWindow = SW_HIDE;
 
-     }
 
-   //std::cout << "Create process: " << s2 << std::endl;
 
-   if (CreateProcess(NULL,
 
-                     s2,
 
-                     NULL,
 
-                     NULL,
 
-                     TRUE,
 
-                     0, //CREATE_NEW_CONSOLE,
 
-                     NULL,
 
-                     path,
 
-                     &siStartInfo,
 
-                     &piProcInfo) ) 
 
-     {
 
-     /* Close the handles now so anyone waiting is woken. */
 
-     CloseHandle(piProcInfo.hThread);
 
-     /* Return process handle */
 
-     *hProcess = piProcInfo.hProcess;
 
-     //std::cout << "Process created..." << std::endl;
 
-     free(s2);
 
-     free(s1);
 
-     return TRUE;
 
-     }
 
-   
 
-    LPVOID lpMsgBuf;
 
-   FormatMessage( 
 
-                 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
 
-                 NULL,
 
-                 GetLastError(),
 
-                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
 
-                 (LPTSTR) &lpMsgBuf,
 
-                 0,
 
-                 NULL 
 
-                 );
 
-   
 
-   // Free the buffer.
 
-  
 
-   char* str = strcpy(new char[strlen((char*)lpMsgBuf)+1], (char*)lpMsgBuf); 
 
-   LocalFree( lpMsgBuf );
 
-   
 
-   output += "CreateProcessError: ";
 
-   output += str;
 
-   output += "\n";
 
-   output += "for command: ";
 
-   output += s2;
 
-   if(path)
 
-     {
 
-     output += "\nin dir: ";
 
-     output += path;
 
-     }
 
-   output += "\n";
 
-   delete [] str;
 
-   free(s2);
 
-   free(s1);
 
-   return FALSE;
 
- }
 
- /* The following code is based off of KB: Q190351 */
 
- bool cmWin32ProcessExecution::PrivateOpen(const char *cmdstring, 
 
-                                           const char* path,
 
-                                           int mode, 
 
-                                           int n)
 
- {
 
-   HANDLE hProcess;
 
-   SECURITY_ATTRIBUTES saAttr;
 
-   BOOL fSuccess;
 
-   int fd1, fd2, fd3;
 
-   this->hChildStdinRd = 0;
 
-   this->hChildStdinWr = 0;
 
-   this->hChildStdoutRd = 0;
 
-   this->hChildStdoutWr = 0;
 
-   this->hChildStderrRd = 0;
 
-   this->hChildStderrWr = 0;
 
-   this->hChildStdinWrDup = 0;
 
-   this->hChildStdoutRdDup = 0;
 
-   this->hChildStderrRdDup = 0;
 
-   
 
-   saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
 
-   saAttr.bInheritHandle = TRUE;
 
-   saAttr.lpSecurityDescriptor = NULL;
 
-   
 
-   if (!CreatePipe(&this->hChildStdinRd, &this->hChildStdinWr, &saAttr, 0))
 
-     {
 
-     this->Output += "CreatePipeError\n";
 
-     return false;
 
-     }
 
-     
 
-   /* Create new output read handle and the input write handle. Set
 
-    * the inheritance properties to FALSE. Otherwise, the child inherits
 
-    * the these handles; resulting in non-closeable handles to the pipes
 
-    * being created. */
 
-   fSuccess = DuplicateHandle(GetCurrentProcess(), this->hChildStdinWr,
 
-                              GetCurrentProcess(), &this->hChildStdinWrDup, 0,
 
-                              FALSE,
 
-                              DUPLICATE_SAME_ACCESS);
 
-   if (!fSuccess)
 
-     {
 
-     this->Output += "DuplicateHandleError\n";
 
-     return false;
 
-     }
 
-   /* Close the inheritable version of ChildStdin
 
-      that we're using. */
 
-   CloseHandle(hChildStdinWr);
 
-   if (!CreatePipe(&this->hChildStdoutRd, &this->hChildStdoutWr, &saAttr, 0))
 
-     {
 
-     this->Output += "CreatePipeError\n";
 
-     return false;
 
-     }
 
-   fSuccess = DuplicateHandle(GetCurrentProcess(), this->hChildStdoutRd,
 
-                              GetCurrentProcess(), &this->hChildStdoutRdDup, 0,
 
-                              FALSE, DUPLICATE_SAME_ACCESS);
 
-   if (!fSuccess)
 
-     {
 
-     this->Output += "DuplicateHandleError\n";
 
-     return false;
 
-     }
 
-   /* Close the inheritable version of ChildStdout
 
-      that we're using. */
 
-   CloseHandle(hChildStdoutRd);
 
-   if (n != POPEN_4) 
 
-     {
 
-     if (!CreatePipe(&this->hChildStderrRd, &this->hChildStderrWr, &saAttr, 0))
 
-       {
 
-       this->Output += "CreatePipeError\n";
 
-       return false;
 
-       }
 
-    fSuccess = DuplicateHandle(GetCurrentProcess(),
 
-                               this->hChildStderrRd,
 
-                               GetCurrentProcess(),
 
-                               &this->hChildStderrRdDup, 0,
 
-                               FALSE, DUPLICATE_SAME_ACCESS);
 
-     if (!fSuccess)
 
-       {
 
-       this->Output += "DuplicateHandleError\n";
 
-       return false;
 
-       }
 
-     /* Close the inheritable version of ChildStdErr that we're using. */
 
-     CloseHandle(hChildStderrRd);
 
-     }
 
-           
 
-   switch (n) 
 
-     {
 
-     case POPEN_1:
 
-       switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) 
 
-         {
 
-         case _O_WRONLY | _O_TEXT:
 
-           /* Case for writing to child Stdin in text mode. */
 
-           fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
 
-           /* We don't care about these pipes anymore,
 
-              so close them. */
 
-           break;
 
-         case _O_RDONLY | _O_TEXT:
 
-           /* Case for reading from child Stdout in text mode. */
 
-           fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
 
-           /* We don't care about these pipes anymore,
 
-              so close them. */
 
-           break;
 
-         case _O_RDONLY | _O_BINARY:
 
-           /* Case for readinig from child Stdout in
 
-              binary mode. */
 
-           fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
 
-           /* We don't care about these pipes anymore,
 
-              so close them. */
 
-           break;
 
-         case _O_WRONLY | _O_BINARY:
 
-           /* Case for writing to child Stdin in binary mode. */
 
-           fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
 
-           /* We don't care about these pipes anymore,
 
-              so close them. */
 
-           break;
 
-         }
 
-       break;
 
-         
 
-     case POPEN_2:
 
-     case POPEN_4: 
 
-       //if ( 1 ) 
 
-         {
 
-         fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
 
-         fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
 
-         break;
 
-         }
 
-         
 
-     case POPEN_3:
 
-       //if ( 1) 
 
-         {
 
-         fd1 = _open_osfhandle(TO_INTPTR(this->hChildStdinWrDup), mode);
 
-         fd2 = _open_osfhandle(TO_INTPTR(this->hChildStdoutRdDup), mode);
 
-         fd3 = _open_osfhandle(TO_INTPTR(this->hChildStderrRdDup), mode);
 
-         break;
 
-         }
 
-     }
 
-   if (n == POPEN_4) 
 
-     {
 
-     if (!RealPopenCreateProcess(cmdstring,
 
-                                 path,
 
-                                 this->ConsoleSpawn.c_str(),
 
-                                 this->hChildStdinRd,
 
-                                 this->hChildStdoutWr,
 
-                                 this->hChildStdoutWr,
 
-                                 &hProcess, this->HideWindows,
 
-                                 this->Output))
 
-       return 0;
 
-     }
 
-   else 
 
-     {
 
-     if (!RealPopenCreateProcess(cmdstring,
 
-                                 path,
 
-                                 this->ConsoleSpawn.c_str(),
 
-                                 this->hChildStdinRd,
 
-                                 this->hChildStdoutWr,
 
-                                 this->hChildStderrWr,
 
-                                 &hProcess, this->HideWindows,
 
-                                 this->Output))
 
-       return 0;
 
-     }
 
-   /*
 
-    * Insert the files we've created into the process dictionary
 
-    * all referencing the list with the process handle and the
 
-    * initial number of files (see description below in _PyPclose).
 
-    * Since if _PyPclose later tried to wait on a process when all
 
-    * handles weren't closed, it could create a deadlock with the
 
-    * child, we spend some energy here to try to ensure that we
 
-    * either insert all file handles into the dictionary or none
 
-    * at all.  It's a little clumsy with the various popen modes
 
-    * and variable number of files involved.
 
-    */
 
-   /* Child is launched. Close the parents copy of those pipe
 
-    * handles that only the child should have open.  You need to
 
-    * make sure that no handles to the write end of the output pipe
 
-    * are maintained in this process or else the pipe will not close
 
-    * when the child process exits and the ReadFile will hang. */
 
-   this->ProcessHandle = hProcess;
 
-   if ( fd1 >= 0 )
 
-     {
 
-     //  this->StdIn = f1;
 
-     this->pStdIn = fd1;
 
-     }
 
-   if ( fd2 >= 0 )
 
-     {
 
-     //  this->StdOut = f2;
 
-     this->pStdOut = fd2;
 
-     }
 
-   if ( fd3 >= 0 )
 
-     {
 
-     //  this->StdErr = f3;
 
-     this->pStdErr = fd3;
 
-     }
 
-   return true;
 
- }
 
- bool cmWin32ProcessExecution::CloseHandles()
 
- {
 
-   bool ret = true;
 
-   if (this->hChildStdinRd && !CloseHandle(this->hChildStdinRd))
 
-     {
 
-     this->Output += "CloseHandleError\n";
 
-     ret = false;
 
-     }
 
-   this->hChildStdinRd = 0;
 
-   if(this->hChildStdoutRdDup && !CloseHandle(this->hChildStdoutRdDup))
 
-     {
 
-     this->Output += "CloseHandleError\n";
 
-     ret = false;
 
-     }
 
-   this->hChildStdoutRdDup = 0;
 
-   if(this->hChildStderrRdDup && !CloseHandle(this->hChildStderrRdDup))
 
-     {
 
-     this->Output += "CloseHandleError\n";
 
-     ret = false;
 
-     }
 
-   this->hChildStderrRdDup = 0;
 
-   if(this->hChildStdinWrDup && !CloseHandle(this->hChildStdinWrDup))
 
-     {
 
-     this->Output += "CloseHandleError\n";
 
-     ret = false;
 
-     }
 
-   this->hChildStdinWrDup = 0;
 
-   if (this->hChildStdoutWr && !CloseHandle(this->hChildStdoutWr))
 
-     {
 
-     this->Output += "CloseHandleError\n";
 
-     ret = false;
 
-     }
 
-   this->hChildStdoutWr = 0;
 
-   if (this->hChildStderrWr && !CloseHandle(this->hChildStderrWr))
 
-     {
 
-     this->Output += "CloseHandleError\n";
 
-     ret = false;
 
-     }
 
-   this->hChildStderrWr = 0;
 
-   return ret;
 
- }
 
- cmWin32ProcessExecution::~cmWin32ProcessExecution()
 
- {
 
-   this->CloseHandles();
 
- }
 
- /*
 
-  * Wrapper for fclose() to use for popen* files, so we can retrieve the
 
-  * exit code for the child process and return as a result of the close.
 
-  *
 
-  * This function uses the _PyPopenProcs dictionary in order to map the
 
-  * input file pointer to information about the process that was
 
-  * originally created by the popen* call that created the file pointer.
 
-  * The dictionary uses the file pointer as a key (with one entry
 
-  * inserted for each file returned by the original popen* call) and a
 
-  * single list object as the value for all files from a single call.
 
-  * The list object contains the Win32 process handle at [0], and a file
 
-  * count at [1], which is initialized to the total number of file
 
-  * handles using that list.
 
-  *
 
-  * This function closes whichever handle it is passed, and decrements
 
-  * the file count in the dictionary for the process handle pointed to
 
-  * by this file.  On the last close (when the file count reaches zero),
 
-  * this function will wait for the child process and then return its
 
-  * exit code as the result of the close() operation.  This permits the
 
-  * files to be closed in any order - it is always the close() of the
 
-  * final handle that will return the exit code.
 
-  */
 
-  /* RED_FLAG 31-Aug-2000 Tim
 
-   * This is always called (today!) between a pair of
 
-   * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
 
-   * macros.  So the thread running this has no valid thread state, as
 
-   * far as Python is concerned.  However, this calls some Python API
 
-   * functions that cannot be called safely without a valid thread
 
-   * state, in particular PyDict_GetItem.
 
-   * As a temporary hack (although it may last for years ...), we
 
-   * *rely* on not having a valid thread state in this function, in
 
-   * order to create our own "from scratch".
 
-   * This will deadlock if _PyPclose is ever called by a thread
 
-   * holding the global lock.
 
-   */
 
- bool cmWin32ProcessExecution::PrivateClose(int /* timeout */)
 
- {
 
-   HANDLE hProcess = this->ProcessHandle;
 
-   int result = -1;
 
-   DWORD exit_code;
 
-   std::string output = "";
 
-   bool done = false;
 
-   while(!done)
 
-     {
 
-     Sleep(10);
 
-     bool have_some = false;
 
-     struct _stat fsout;
 
-     struct _stat fserr;
 
-     int rout = _fstat(this->pStdOut, &fsout);
 
-     int rerr = _fstat(this->pStdErr, &fserr);
 
-     if ( rout && rerr )
 
-       {
 
-       break;
 
-       }
 
-     if (fserr.st_size > 0)
 
-       {
 
-       char buffer[1024];
 
-       int len = read(this->pStdErr, buffer, 1023);
 
-       buffer[len] = 0;
 
-       if ( this->Verbose )
 
-         {
 
-         cmSystemTools::Stdout(buffer);
 
-         }
 
-       output += buffer;
 
-       have_some = true;
 
-       }
 
-     if (fsout.st_size > 0)
 
-       {
 
-       char buffer[1024];
 
-       int len = read(this->pStdOut, buffer, 1023);
 
-       buffer[len] = 0;
 
-       if ( this->Verbose )
 
-         {
 
-         cmSystemTools::Stdout(buffer);
 
-         }
 
-       output += buffer;
 
-       have_some = true;
 
-       }
 
-     unsigned long exitCode;
 
-     if ( ! have_some )
 
-       {
 
-       GetExitCodeProcess(hProcess,&exitCode);
 
-       if (exitCode != STILL_ACTIVE)
 
-         {
 
-         break;
 
-         }
 
-       }
 
-     }  
 
-   
 
-   if (WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
 
-       GetExitCodeProcess(hProcess, &exit_code)) 
 
-     {
 
-     result = exit_code;
 
-     } 
 
-   else 
 
-     {
 
-     /* Indicate failure - this will cause the file object
 
-      * to raise an I/O error and translate the last Win32
 
-      * error code from errno.  We do have a problem with
 
-      * last errors that overlap the normal errno table,
 
-      * but that's a consistent problem with the file object.
 
-      */
 
-     if (result != EOF) 
 
-       {
 
-       /* If the error wasn't from the fclose(), then
 
-        * set errno for the file object error handling.
 
-        */
 
-       errno = GetLastError();
 
-       }
 
-     result = -1;
 
-     }
 
-   /* Free up the native handle at this point */
 
-   CloseHandle(hProcess);
 
-   this->ExitValue = result;
 
-   this->Output += output;
 
-   bool ret = this->CloseHandles();
 
-   if ( result < 0 || !ret)
 
-     {
 
-     return false;
 
-     }
 
-   return true;
 
- }
 
- int cmWin32ProcessExecution::Windows9xHack(const char* command)
 
- {
 
-   BOOL bRet;
 
-   STARTUPINFO si;
 
-   PROCESS_INFORMATION pi;
 
-   DWORD exit_code=0;
 
-   if (!command) 
 
-     {
 
-     cmSystemTools::Error("Windows9xHack: Command not specified");
 
-     return 1;
 
-   }
 
-   /* Make child process use this app's standard files. */
 
-   ZeroMemory(&si, sizeof si);
 
-   si.cb = sizeof si;
 
-   si.dwFlags = STARTF_USESTDHANDLES;
 
-   si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
 
-   si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
 
-   si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
 
-   
 
-   char * app = 0;
 
-   char* cmd = new char[ strlen(command) + 1 ];
 
-   strcpy(cmd, command);
 
-   bRet = CreateProcess(
 
-     app, cmd,
 
-     0, 0,
 
-     TRUE, 0,
 
-     0, 0,
 
-     &si, &pi
 
-     );
 
-   delete [] cmd;
 
-   if (bRet) 
 
-     {
 
-     if (WaitForSingleObject(pi.hProcess, INFINITE) != WAIT_FAILED) 
 
-       {
 
-       GetExitCodeProcess(pi.hProcess, &exit_code);
 
-       }
 
-     CloseHandle(pi.hProcess);
 
-     CloseHandle(pi.hThread);
 
-     return exit_code;
 
-     }
 
-   return 1;
 
- }
 
 
  |