| #include <dds/proc.hpp> | #include <dds/proc.hpp> | ||||
| #include <dds/util/algo.hpp> | #include <dds/util/algo.hpp> | ||||
| #include <dds/util/signal.hpp> | |||||
| #include <spdlog/spdlog.h> | #include <spdlog/spdlog.h> | ||||
| lk.unlock(); | lk.unlock(); | ||||
| try { | try { | ||||
| compilation.compile(tc); | compilation.compile(tc); | ||||
| cancellation_point(); | |||||
| } catch (...) { | } catch (...) { | ||||
| lk.lock(); | lk.lock(); | ||||
| exceptions.push_back(std::current_exception()); | exceptions.push_back(std::current_exception()); |
| return 1; | return 1; | ||||
| } | } | ||||
| dds::install_signal_handlers(); | |||||
| try { | try { | ||||
| if (build.cmd) { | if (build.cmd) { | ||||
| return build.run(); | return build.run(); |
| #ifndef _WIN32 | #ifndef _WIN32 | ||||
| #include "./proc.hpp" | #include "./proc.hpp" | ||||
| #include <dds/util/signal.hpp> | |||||
| #include <spdlog/fmt/fmt.h> | #include <spdlog/fmt/fmt.h> | ||||
| #include <poll.h> | #include <poll.h> | ||||
| while (true) { | while (true) { | ||||
| rc = ::poll(&stdio_fd, 1, -1); | rc = ::poll(&stdio_fd, 1, -1); | ||||
| if (rc && errno == EINTR) { | |||||
| errno = 0; | |||||
| continue; | |||||
| } | |||||
| check_rc(rc > 0, "Failed in poll()"); | check_rc(rc > 0, "Failed in poll()"); | ||||
| std::string buffer; | std::string buffer; | ||||
| buffer.resize(1024); | buffer.resize(1024); | ||||
| } else if (WIFSIGNALED(status)) { | } else if (WIFSIGNALED(status)) { | ||||
| res.signal = WTERMSIG(status); | res.signal = WTERMSIG(status); | ||||
| } | } | ||||
| cancellation_point(); | |||||
| return res; | return res; | ||||
| } | } | ||||
| #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(); | |||||
| } | |||||
| } |
| #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 |