| @@ -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 | |||