@@ -2,6 +2,7 @@ | |||
#include <dds/proc.hpp> | |||
#include <dds/util/algo.hpp> | |||
#include <dds/util/signal.hpp> | |||
#include <spdlog/spdlog.h> | |||
@@ -81,6 +82,7 @@ void dds::execute_all(const std::vector<file_compilation>& compilations, | |||
lk.unlock(); | |||
try { | |||
compilation.compile(tc); | |||
cancellation_point(); | |||
} catch (...) { | |||
lk.lock(); | |||
exceptions.push_back(std::current_exception()); |
@@ -172,6 +172,8 @@ int main(int argc, char** argv) { | |||
return 1; | |||
} | |||
dds::install_signal_handlers(); | |||
try { | |||
if (build.cmd) { | |||
return build.run(); |
@@ -1,6 +1,8 @@ | |||
#ifndef _WIN32 | |||
#include "./proc.hpp" | |||
#include <dds/util/signal.hpp> | |||
#include <spdlog/fmt/fmt.h> | |||
#include <poll.h> | |||
@@ -79,6 +81,10 @@ proc_result dds::run_proc(const std::vector<std::string>& command) { | |||
while (true) { | |||
rc = ::poll(&stdio_fd, 1, -1); | |||
if (rc && errno == EINTR) { | |||
errno = 0; | |||
continue; | |||
} | |||
check_rc(rc > 0, "Failed in poll()"); | |||
std::string buffer; | |||
buffer.resize(1024); | |||
@@ -99,6 +105,8 @@ proc_result dds::run_proc(const std::vector<std::string>& command) { | |||
} else if (WIFSIGNALED(status)) { | |||
res.signal = WTERMSIG(status); | |||
} | |||
cancellation_point(); | |||
return res; | |||
} | |||
@@ -0,0 +1,27 @@ | |||
#include "./signal.hpp" | |||
#include <csignal> | |||
namespace { | |||
std::sig_atomic_t got_signal = 0; | |||
void handle_signal(int sig) { got_signal = sig; } | |||
} // namespace | |||
using namespace dds; | |||
void dds::notify_cancel() noexcept { got_signal = SIGINT; } | |||
void dds::install_signal_handlers() noexcept { | |||
std::signal(SIGINT, handle_signal); | |||
std::signal(SIGTERM, handle_signal); | |||
} | |||
bool dds::is_cancelled() noexcept { return got_signal != 0; } | |||
void dds::cancellation_point() { | |||
if (is_cancelled()) { | |||
throw user_cancelled(); | |||
} | |||
} |
@@ -0,0 +1,16 @@ | |||
#pragma once | |||
#include <stdexcept> | |||
namespace dds { | |||
class user_cancelled : public std::exception {}; | |||
void install_signal_handlers() noexcept; | |||
void notify_cancel() noexcept; | |||
void reset_cancelled() noexcept; | |||
bool is_cancelled() noexcept; | |||
void cancellation_point(); | |||
} // namespace dds |