Ninja
subprocess.h
Go to the documentation of this file.
1 // Copyright 2012 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef NINJA_SUBPROCESS_H_
16 #define NINJA_SUBPROCESS_H_
17 
18 #include <string>
19 #include <vector>
20 #include <queue>
21 using namespace std;
22 
23 #ifdef _WIN32
24 #include <windows.h>
25 #else
26 #include <signal.h>
27 #endif
28 
29 #include "exit_status.h"
30 
31 /// Subprocess wraps a single async subprocess. It is entirely
32 /// passive: it expects the caller to notify it when its fds are ready
33 /// for reading, as well as call Finish() to reap the child once done()
34 /// is true.
35 struct Subprocess {
36  ~Subprocess();
37 
38  /// Returns ExitSuccess on successful process exit, ExitInterrupted if
39  /// the process was interrupted, ExitFailure if it otherwise failed.
40  ExitStatus Finish();
41 
42  bool Done() const;
43 
44  const string& GetOutput() const;
45 
46  private:
47  Subprocess(bool use_console);
48  bool Start(struct SubprocessSet* set, const string& command);
49  void OnPipeReady();
50 
51  string buf_;
52 
53 #ifdef _WIN32
54  /// Set up pipe_ as the parent-side pipe of the subprocess; return the
55  /// other end of the pipe, usable in the child process.
56  HANDLE SetupPipe(HANDLE ioport);
57 
58  HANDLE child_;
59  HANDLE pipe_;
60  OVERLAPPED overlapped_;
61  char overlapped_buf_[4 << 10];
62  bool is_reading_;
63 #else
64  int fd_;
65  pid_t pid_;
66 #endif
68 
69  friend struct SubprocessSet;
70 };
71 
72 /// SubprocessSet runs a ppoll/pselect() loop around a set of Subprocesses.
73 /// DoWork() waits for any state change in subprocesses; finished_
74 /// is a queue of subprocesses as they finish.
75 struct SubprocessSet {
76  SubprocessSet();
77  ~SubprocessSet();
78 
79  Subprocess* Add(const string& command, bool use_console = false);
80  bool DoWork();
81  Subprocess* NextFinished();
82  void Clear();
83 
84  vector<Subprocess*> running_;
85  queue<Subprocess*> finished_;
86 
87 #ifdef _WIN32
88  static BOOL WINAPI NotifyInterrupted(DWORD dwCtrlType);
89  static HANDLE ioport_;
90 #else
91  static void SetInterruptedFlag(int signum);
92  static bool interrupted_;
93 
94  struct sigaction old_act_;
95  sigset_t old_mask_;
96 #endif
97 };
98 
99 #endif // NINJA_SUBPROCESS_H_
SubprocessSet runs a ppoll/pselect() loop around a set of Subprocesses.
Definition: subprocess.h:75
bool use_console_
Definition: subprocess.h:67
IN IN HANDLE
vector< Subprocess * > running_
Definition: subprocess.h:84
string buf_
Definition: subprocess.h:51
Subprocess wraps a single async subprocess.
Definition: subprocess.h:35
ExitStatus
Definition: exit_status.h:18
static bool interrupted_
Definition: subprocess.h:92
sigset_t old_mask_
Definition: subprocess.h:95
pid_t pid_
Definition: subprocess.h:65
typedef BOOL(WINAPI *MiniDumpWriteDumpFunc)(IN HANDLE
queue< Subprocess * > finished_
Definition: subprocess.h:85
IN DWORD