/*=========================================================================

  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 
    {
    return false;
    }
  if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) 
//create stdout pipe 
    {
    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;
    }

  output += "CreateProcessError: ";
  {
  /* Format the error message.  */
  char message[1024];
  DWORD original = GetLastError();
  DWORD length = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
                               FORMAT_MESSAGE_IGNORE_INSERTS, 0, original,
                               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                               message, 1023, 0);
  if(length < 1)
    {
    /* FormatMessage failed.  Use a default message.  */
    _snprintf(message, 1023,
              "Process execution failed with error 0x%X.  "
              "FormatMessage failed with error 0x%X",
              original, GetLastError());
    }
  output += message;
  }
  output += "\n";
  output += "for command: ";
  output += s2;
  if(path)
    {
    output += "\nin dir: ";
    output += path;
    }
  output += "\n";
  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;
  
  fd1 = 0;
  fd2 = 0;
  fd3 = 0;

  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))
      {
      if(fd1 >= 0)
        {
        close(fd1);
        }
      if(fd2 >= 0)
        {
        close(fd2);
        }
      if(fd3 >= 0)
        {
        close(fd3);
        }
      return 0;
      }
    }
  else 
    {
    if (!RealPopenCreateProcess(cmdstring,
                                path,
                                this->ConsoleSpawn.c_str(),
                                this->hChildStdinRd,
                                this->hChildStdoutWr,
                                this->hChildStderrWr,
                                &hProcess, this->HideWindows,
                                this->Output))
      {
      if(fd1 >= 0)
        {
        close(fd1);
        }
      if(fd2 >= 0)
        {
        close(fd2);
        }
      if(fd3 >= 0)
        {
        close(fd3);
        }
      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->pStdIn = fd1;
    }
  if ( fd2 >= 0 )
    {
    this->pStdOut = fd2;
    }
  if ( fd3 >= 0 )
    {
    this->pStdErr = fd3;
    }

  return true;
}

bool cmWin32ProcessExecution::CloseHandles()
{
  if(this->pStdErr != -1 )
    {
    _close(this->pStdErr);
    this->pStdErr = -1;
    }
  if(this->pStdIn != -1 )
    {
    _close(this->pStdIn);
    this->pStdIn = -1;
    }
  if(this->pStdOut != -1 )
    {
    _close(this->pStdOut);
    this->pStdOut = -1;
    }

  bool ret = true;
  if (this->hChildStdinRd && !CloseHandle(this->hChildStdinRd))
    {
    ret = false;
    }
  this->hChildStdinRd = 0;
  if(this->hChildStdoutRdDup && !CloseHandle(this->hChildStdoutRdDup))
    {
    ret = false;
    }
  this->hChildStdoutRdDup = 0;
  if(this->hChildStderrRdDup && !CloseHandle(this->hChildStderrRdDup))
    {
    ret = false;
    }
  this->hChildStderrRdDup = 0;
  if(this->hChildStdinWrDup && !CloseHandle(this->hChildStdinWrDup))
    {
    ret = false;
    }
  this->hChildStdinWrDup = 0;
  if (this->hChildStdoutWr && !CloseHandle(this->hChildStdoutWr))
    {
    ret = false;
    }
  this->hChildStdoutWr = 0;
  if (this->hChildStderrWr && !CloseHandle(this->hChildStderrWr))
    {
    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;
}
