diff options
author | Brad King <brad.king@kitware.com> | 2013-10-18 20:22:45 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2013-10-19 11:25:43 (GMT) |
commit | 765d783972dbacc336d11803cccf56cdc9aac6c5 (patch) | |
tree | 4bc204bfdf18d96e6cf24e9e9724d4a2c13efcc6 /Source/cmWin32ProcessExecution.cxx | |
parent | 52b80b2643acdd2f31582fe20773cc4c3740b9ad (diff) | |
download | CMake-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.cxx | 884 |
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; -} |