summaryrefslogtreecommitdiffstats
path: root/Source/cmWin32ProcessExecution.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2013-10-18 20:22:45 (GMT)
committerBrad King <brad.king@kitware.com>2013-10-19 11:25:43 (GMT)
commit765d783972dbacc336d11803cccf56cdc9aac6c5 (patch)
tree4bc204bfdf18d96e6cf24e9e9724d4a2c13efcc6 /Source/cmWin32ProcessExecution.cxx
parent52b80b2643acdd2f31582fe20773cc4c3740b9ad (diff)
downloadCMake-765d783972dbacc336d11803cccf56cdc9aac6c5.zip
CMake-765d783972dbacc336d11803cccf56cdc9aac6c5.tar.gz
CMake-765d783972dbacc336d11803cccf56cdc9aac6c5.tar.bz2
cmSystemTools: Drop old RunCommand method
All calls to this method have been replaced by newer infrastructure. Remove it and the supporting cmWin32ProcessExecution class.
Diffstat (limited to 'Source/cmWin32ProcessExecution.cxx')
-rw-r--r--Source/cmWin32ProcessExecution.cxx884
1 files changed, 0 insertions, 884 deletions
diff --git a/Source/cmWin32ProcessExecution.cxx b/Source/cmWin32ProcessExecution.cxx
deleted file mode 100644
index 1bdeffb..0000000
--- a/Source/cmWin32ProcessExecution.cxx
+++ /dev/null
@@ -1,884 +0,0 @@
-/*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
-
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License 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))
-#endif // Borland
-#if defined(_MSC_VER) // 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 // Visual Studio
-#if defined(__MINGW32__)
-# include <stdint.h>
-# define TO_INTPTR(x) ((intptr_t)(x))
-# define STRICMP _stricmp
-#endif // MinGW
-
-#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);
-}
-
-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;
- const char *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
- * 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;
- }
- }
-
- /* 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 )
- {
- // this will close this as well: this->hChildStderrRdDup
- _close(this->pStdErr);
- this->pStdErr = -1;
- this->hChildStderrRdDup = 0;
- }
- if(this->pStdIn != -1 )
- {
- // this will close this as well: this->hChildStdinWrDup
- _close(this->pStdIn);
- this->pStdIn = -1;
- this->hChildStdinWrDup = 0;
- }
- if(this->pStdOut != -1 )
- {
- // this will close this as well: this->hChildStdoutRdDup
- _close(this->pStdOut);
- this->pStdOut = -1;
- this->hChildStdoutRdDup = 0;
- }
-
- bool ret = true;
- if (this->hChildStdinRd && !CloseHandle(this->hChildStdinRd))
- {
- ret = false;
- }
- this->hChildStdinRd = 0;
- // now close these two
- 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();
-}
-
-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;
-}