diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2011-11-13 05:49:16 (GMT) |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2012-02-04 21:46:12 (GMT) |
commit | 85ff781fa30fff63c01ccd30faaad39d766e1505 (patch) | |
tree | dc5791da4769c61951735e84febcccfa8acf98d2 /src/subprocess.h | |
parent | b07e183e0eb6225e34a3d592e3dff63bcf00df81 (diff) | |
download | Ninja-85ff781fa30fff63c01ccd30faaad39d766e1505.zip Ninja-85ff781fa30fff63c01ccd30faaad39d766e1505.tar.gz Ninja-85ff781fa30fff63c01ccd30faaad39d766e1505.tar.bz2 |
Implement cleanup-on-interrupt
This causes us to clean up by deleting any output files belonging
to currently-running commands before we quit if we are interrupted
(either by Ctrl-C or by a command failing).
Fixes issue #110.
Diffstat (limited to 'src/subprocess.h')
-rw-r--r-- | src/subprocess.h | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/subprocess.h b/src/subprocess.h index 9828bf4..5150eea 100644 --- a/src/subprocess.h +++ b/src/subprocess.h @@ -22,25 +22,32 @@ using namespace std; #ifdef _WIN32 #include <windows.h> +#else +#include <signal.h> #endif +#include "exit_status.h" + /// Subprocess wraps a single async subprocess. It is entirely /// passive: it expects the caller to notify it when its fds are ready /// for reading, as well as call Finish() to reap the child once done() /// is true. struct Subprocess { - Subprocess(); ~Subprocess(); - bool Start(struct SubprocessSet* set, const string& command); - void OnPipeReady(); - /// Returns true on successful process exit. - bool Finish(); + + /// Returns ExitSuccess on successful process exit, ExitInterrupted if + /// the process was interrupted, ExitFailure if it otherwise failed. + ExitStatus Finish(); bool Done() const; const string& GetOutput() const; private: + Subprocess(); + bool Start(struct SubprocessSet* set, const string& command); + void OnPipeReady(); + string buf_; #ifdef _WIN32 @@ -60,22 +67,30 @@ struct Subprocess { friend struct SubprocessSet; }; -/// SubprocessSet runs a poll() loop around a set of Subprocesses. +/// SubprocessSet runs a pselect() loop around a set of Subprocesses. /// DoWork() waits for any state change in subprocesses; finished_ /// is a queue of subprocesses as they finish. struct SubprocessSet { SubprocessSet(); ~SubprocessSet(); - void Add(Subprocess* subprocess); - void DoWork(); + Subprocess *Add(const string &command); + bool DoWork(); Subprocess* NextFinished(); + void Clear(); vector<Subprocess*> running_; queue<Subprocess*> finished_; #ifdef _WIN32 - HANDLE ioport_; + static BOOL WINAPI NotifyInterrupted(DWORD dwCtrlType); + static HANDLE ioport_; +#else + static void SetInterruptedFlag(int signum); + static bool interrupted_; + + struct sigaction old_act_; + sigset_t old_mask_; #endif }; |