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 
22 #ifdef _WIN32
23 #include <windows.h>
24 #else
25 #include <signal.h>
26 #endif
27 
28 // ppoll() exists on FreeBSD, but only on newer versions.
29 #ifdef __FreeBSD__
30 # include <sys/param.h>
31 # if defined USE_PPOLL && __FreeBSD_version < 1002000
32 # undef USE_PPOLL
33 # endif
34 #endif
35 
36 #include "exit_status.h"
37 
38 /// Subprocess wraps a single async subprocess. It is entirely
39 /// passive: it expects the caller to notify it when its fds are ready
40 /// for reading, as well as call Finish() to reap the child once done()
41 /// is true.
42 struct Subprocess {
43  ~Subprocess();
44 
45  /// Returns ExitSuccess on successful process exit, ExitInterrupted if
46  /// the process was interrupted, ExitFailure if it otherwise failed.
48 
49  bool Done() const;
50 
51  const std::string& GetOutput() const;
52 
53  private:
54  Subprocess(bool use_console);
55  bool Start(struct SubprocessSet* set, const std::string& command);
56  void OnPipeReady();
57 
58  std::string buf_;
59 
60 #ifdef _WIN32
61  /// Set up pipe_ as the parent-side pipe of the subprocess; return the
62  /// other end of the pipe, usable in the child process.
63  HANDLE SetupPipe(HANDLE ioport);
64 
65  HANDLE child_;
66  HANDLE pipe_;
67  OVERLAPPED overlapped_;
68  char overlapped_buf_[4 << 10];
69  bool is_reading_;
70 #else
71  int fd_;
72  pid_t pid_;
73 #endif
75 
76  friend struct SubprocessSet;
77 };
78 
79 /// SubprocessSet runs a ppoll/pselect() loop around a set of Subprocesses.
80 /// DoWork() waits for any state change in subprocesses; finished_
81 /// is a queue of subprocesses as they finish.
82 struct SubprocessSet {
83  SubprocessSet();
85 
86  Subprocess* Add(const std::string& command, bool use_console = false);
87  bool DoWork();
89  void Clear();
90 
91  std::vector<Subprocess*> running_;
92  std::queue<Subprocess*> finished_;
93 
94 #ifdef _WIN32
95  static BOOL WINAPI NotifyInterrupted(DWORD dwCtrlType);
96  static HANDLE ioport_;
97 #else
98  static void SetInterruptedFlag(int signum);
99  static void HandlePendingInterruption();
100  /// Store the signal number that causes the interruption.
101  /// 0 if not interruption.
102  static int interrupted_;
103 
104  static bool IsInterrupted() { return interrupted_ != 0; }
105 
106  struct sigaction old_int_act_;
107  struct sigaction old_term_act_;
108  struct sigaction old_hup_act_;
109  sigset_t old_mask_;
110 #endif
111 };
112 
113 #endif // NINJA_SUBPROCESS_H_
Subprocess * Add(const std::string &command, bool use_console=false)
SubprocessSet runs a ppoll/pselect() loop around a set of Subprocesses.
Definition: subprocess.h:82
std::queue< Subprocess * > finished_
Definition: subprocess.h:92
bool use_console_
Definition: subprocess.h:74
static void SetInterruptedFlag(int signum)
Subprocess * NextFinished()
ExitStatus Finish()
Returns ExitSuccess on successful process exit, ExitInterrupted if the process was interrupted...
bool Start(struct SubprocessSet *set, const std::string &command)
struct sigaction old_int_act_
Definition: subprocess.h:106
Subprocess wraps a single async subprocess.
Definition: subprocess.h:42
static bool IsInterrupted()
Definition: subprocess.h:104
static int interrupted_
Store the signal number that causes the interruption.
Definition: subprocess.h:102
struct sigaction old_hup_act_
Definition: subprocess.h:108
ExitStatus
Definition: exit_status.h:18
Subprocess(bool use_console)
sigset_t old_mask_
Definition: subprocess.h:109
pid_t pid_
Definition: subprocess.h:72
std::string buf_
Definition: subprocess.h:58
static void HandlePendingInterruption()
const std::string & GetOutput() const
bool Done() const
std::vector< Subprocess * > running_
Definition: subprocess.h:91
struct sigaction old_term_act_
Definition: subprocess.h:107