summaryrefslogtreecommitdiffstats
path: root/src/subprocess.h
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2011-11-13 05:49:16 (GMT)
committerPeter Collingbourne <peter@pcc.me.uk>2012-02-04 21:46:12 (GMT)
commit85ff781fa30fff63c01ccd30faaad39d766e1505 (patch)
treedc5791da4769c61951735e84febcccfa8acf98d2 /src/subprocess.h
parentb07e183e0eb6225e34a3d592e3dff63bcf00df81 (diff)
downloadNinja-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.h33
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
};