PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/Source/cmWin32ProcessExecution.h

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