diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/src/main.cpp b/src/main.cpp index 8b77545..8dde449 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,7 +3,11 @@ #include <unistd.h> +#include <signal.h> #include <sys/poll.h> +#include <sys/signalfd.h> + +#include <algorithm> struct connection { std::vector<std::unique_ptr<wl::output>> outputs; @@ -26,13 +30,14 @@ struct Poller { }; void Poller::add_fd(int fd, std::function<int(int)> handler) { - pfds.emplace_back(pollfd{ .fd = fd, .events = POLLIN, .revents = 0 }); + pfds.emplace_back(pollfd{.fd = fd, .events = POLLIN, .revents = 0}); handlers.emplace_back(std::move(handler)); } int Poller::check_events() { int ret = 0; - if ((ret = poll(this->pfds.data(), this->pfds.size(), -1)) != -1 && errno != EINTR) { + if ((ret = poll(this->pfds.data(), this->pfds.size(), -1)) != -1 && + errno != EINTR) { for (unsigned i = 0; i < pfds.size(); i++) { if (pfds[i].revents & POLLIN) { if (handlers[i](pfds[i].fd) == -1) { @@ -46,6 +51,25 @@ int Poller::check_events() { return ret; } +struct unique_fd { + int fd {-1}; + unique_fd() = default; + explicit unique_fd(int f) : fd{f} {} + operator int() const { return fd; } + ~unique_fd() { + if (this->fd != -1) + close(this->fd); + } + unique_fd(unique_fd const &) = delete; + unique_fd &operator=(unique_fd const &) = delete; + unique_fd(unique_fd &&o) : fd(o.fd) { o.fd = -1; } + unique_fd &operator=(unique_fd &&o) { + std::swap(this->fd, o.fd); + return *this; + } +}; + + namespace { // _ _ _ _ _ ____ // (_)_ __ (_) |_ | | __ _ _ _ ___ _ _| |_ / /\ \ @@ -160,9 +184,27 @@ int main(int /*argc*/, char ** /*argv*/) { return d.dispatch(); }); + sigset_t sset{}; + sigemptyset(&sset); + sigaddset(&sset, SIGINT); + sigaddset(&sset, SIGTERM); + + auto sfd = unique_fd(signalfd(-1, &sset, SFD_NONBLOCK | SFD_CLOEXEC)); + sigprocmask(SIG_BLOCK, &sset, NULL); + p.add_fd(sfd.fd, [](int fd) { + struct signalfd_siginfo si; + while (read(fd, &si, sizeof(si)) == sizeof(si)) { + lognotice("Received signal %u", si.ssi_signo); + } + return -1; + }); + while ((d.flush(), p.check_events()) != -1) { c.c->execute_pending(); } + c.c->commit_changes(); + d.roundtrip(); + return 0; } |