cmWin32ProcessExecution.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #ifndef cmWin32ProcessExecution_h
  14. #define cmWin32ProcessExecution_h
  15. #include "cmStandardIncludes.h"
  16. #include "windows.h"
  17. class cmMakefile;
  18. /** \class cmWin32ProcessExecution
  19. * \brief A process executor for windows
  20. *
  21. * cmWin32ProcessExecution is a class that provides a "clean" way of
  22. * executing processes on Windows. It is modified code from Python 2.1
  23. * distribution.
  24. *
  25. * Portable 'popen' replacement for Win32.
  26. *
  27. * Written by Bill Tutt <[email protected]>. Minor tweaks and 2.0
  28. * integration by Fredrik Lundh <[email protected]> Return code
  29. * handling by David Bolen <[email protected]>.
  30. *
  31. * Modified for CMake.
  32. *
  33. * For more information, please check Microsoft Knowledge Base
  34. * Articles Q190351 and Q150956.
  35. */
  36. class cmWin32ProcessExecution
  37. {
  38. public:
  39. cmWin32ProcessExecution()
  40. {
  41. this->HideWindows = false;
  42. this->SetConsoleSpawn("w9xpopen.exe");
  43. this->Initialize();
  44. }
  45. ~cmWin32ProcessExecution();
  46. ///! If true windows will be created hidden.
  47. void SetHideWindows(bool v) { this->HideWindows = v; }
  48. /**
  49. * Initialize the process execution datastructure. Do not call while
  50. * running the process.
  51. */
  52. void Initialize()
  53. {
  54. this->ProcessHandle = 0;
  55. this->ExitValue = -1;
  56. // Comment this out. Maybe we will need it in the future.
  57. // file IO access to the process might be cool.
  58. //this->StdIn = 0;
  59. //this->StdOut = 0;
  60. //this->StdErr = 0;
  61. this->pStdIn = -1;
  62. this->pStdOut = -1;
  63. this->pStdErr = -1;
  64. }
  65. /**
  66. * Start the process in the directory path. Make sure that the
  67. * executable is either in the path or specify the full path. The
  68. * argument verbose specifies wether or not to display output while
  69. * it is being generated.
  70. */
  71. bool StartProcess(const char*, const char* path, bool verbose);
  72. /**
  73. * Wait for the process to finish. If timeout is specified, it will
  74. * break the process after timeout expires. (Timeout code is not yet
  75. * implemented.
  76. */
  77. bool Wait(int timeout);
  78. /**
  79. * Get the output of the process (mixed stdout and stderr) as
  80. * std::string.
  81. */
  82. const std::string GetOutput() const { return this->Output; }
  83. /**
  84. * Get the return value of the process. If the process is still
  85. * running, the return value is -1.
  86. */
  87. int GetExitValue() const { return this->ExitValue; }
  88. /**
  89. * On Windows 9x there is a bug in the process execution code which
  90. * may result in blocking. That is why this workaround is
  91. * used. Specify the console spawn, which should run the
  92. * Windows9xHack code.
  93. */
  94. void SetConsoleSpawn(const char* prog) { this->ConsoleSpawn = prog; }
  95. static int Windows9xHack(const char* command);
  96. /** Code from a Borland web site with the following explaination :
  97. * In this article, I will explain how to spawn a console
  98. * application and redirect its standard input/output using
  99. * anonymous pipes. An anonymous pipe is a pipe that goes only in
  100. * one direction (read pipe, write pipe, etc.). Maybe you are
  101. * asking, "why would I ever need to do this sort of thing?" One
  102. * example would be a Windows telnet server, where you spawn a shell
  103. * and listen on a port and send and receive data between the shell
  104. * and the socket client. (Windows does not really have a built-in
  105. * remote shell). First, we should talk about pipes. A pipe in
  106. * Windows is simply a method of communication, often between
  107. * process. The SDK defines a pipe as "a communication conduit with
  108. * two ends; a process with a handle to one end can communicate with
  109. * a process having a handle to the other end." In our case, we are
  110. * using "anonymous" pipes, one-way pipes that "transfer data
  111. * between a parent process and a child process or between two child
  112. * processes of the same parent process." It's easiest to imagine a
  113. * pipe as its namesake. An actual pipe running between processes
  114. * that can carry data. We are using anonymous pipes because the
  115. * console app we are spawning is a child process. We use the
  116. * CreatePipe function which will create an anonymous pipe and
  117. * return a read handle and a write handle. We will create two
  118. * pipes, on for stdin and one for stdout. We will then monitor the
  119. * read end of the stdout pipe to check for display on our child
  120. * process. Every time there is something availabe for reading, we
  121. * will display it in our app. Consequently, we check for input in
  122. * our app and send it off to the write end of the stdin pipe.
  123. */
  124. static bool BorlandRunCommand(const char* command, const char* dir,
  125. std::string& output, int& retVal, bool verbose,
  126. int timeout, bool hideWindows);
  127. private:
  128. bool CloseHandles();
  129. bool PrivateOpen(const char*, const char*, int, int);
  130. bool PrivateClose(int timeout);
  131. HANDLE ProcessHandle;
  132. HANDLE hChildStdinRd;
  133. HANDLE hChildStdinWr;
  134. HANDLE hChildStdoutRd;
  135. HANDLE hChildStdoutWr;
  136. HANDLE hChildStderrRd;
  137. HANDLE hChildStderrWr;
  138. HANDLE hChildStdinWrDup;
  139. HANDLE hChildStdoutRdDup;
  140. HANDLE hChildStderrRdDup;
  141. int pStdIn;
  142. int pStdOut;
  143. int pStdErr;
  144. int ExitValue;
  145. std::string Output;
  146. std::string ConsoleSpawn;
  147. bool Verbose;
  148. bool HideWindows;
  149. };
  150. #endif