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