main: handling signals, added simple unique_fd RAII helper
authorMarcus Fritzsch <marcus_fritzsch@mentor.com>
Fri, 30 Jun 2017 11:54:23 +0000 (13:54 +0200)
committerMarcus Fritzsch <marcus_fritzsch@mentor.com>
Tue, 8 Aug 2017 15:24:00 +0000 (17:24 +0200)
Signed-off-by: Marcus Fritzsch <marcus_fritzsch@mentor.com>
src/main.cpp

index 8b77545..8dde449 100644 (file)
@@ -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;
 }