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();
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
67 
68  friend struct SubprocessSet;
69 };
70 
71 /// SubprocessSet runs a ppoll/pselect() loop around a set of Subprocesses.
72 /// DoWork() waits for any state change in subprocesses; finished_
73 /// is a queue of subprocesses as they finish.
74 struct SubprocessSet {
75  SubprocessSet();
76  ~SubprocessSet();
77 
78  Subprocess* Add(const string& command);
79  bool DoWork();
80  Subprocess* NextFinished();
81  void Clear();
82 
83  vector<Subprocess*> running_;
84  queue<Subprocess*> finished_;
85 
86 #ifdef _WIN32
87  static BOOL WINAPI NotifyInterrupted(DWORD dwCtrlType);
88  static HANDLE ioport_;
89 #else
90  static void SetInterruptedFlag(int signum);
91  static bool interrupted_;
92 
93  struct sigaction old_act_;
94  sigset_t old_mask_;
95 #endif
96 };
97 
98 #endif // NINJA_SUBPROCESS_H_
SubprocessSet runs a ppoll/pselect() loop around a set of Subprocesses.
Definition: subprocess.h:74
IN IN HANDLE
vector< Subprocess * > running_
Definition: subprocess.h:83
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:91
sigset_t old_mask_
Definition: subprocess.h:94
pid_t pid_
Definition: subprocess.h:65
typedef BOOL(WINAPI *MiniDumpWriteDumpFunc)(IN HANDLE
queue< Subprocess * > finished_
Definition: subprocess.h:84
IN DWORD