moved Poller and unique_fd from main to util, fixed c++ issues in util
[staging/windowmanager.git] / src / util.cpp
1 #include "util.hpp"
2
3 #include <cerrno>
4 #include <cstdarg>
5 #include <cstdio>
6 #include <cstdlib>
7 #include <ctime>
8
9 #include <unistd.h>
10
11 struct strftime_cache {
12    time_t time;
13    char buf[128];
14 };
15
16 static void log_(char const *log_type, FILE *stream, char const *fmt,
17                  va_list args) {
18    static struct strftime_cache strft;
19
20    time_t t = time(nullptr);
21    if (t != strft.time) {
22       strft.time = t;
23       struct tm tm;
24       struct tm *tmp = localtime_r(&t, &tm);
25       strftime(strft.buf, sizeof(strft.buf), "%Y-%m-%dT%H:%M:%S", tmp);
26    }
27
28    fputs(program_invocation_short_name, stream);
29    fputs("  ", stream);
30    fputs(strft.buf, stream);
31    fputs("  ", stream);
32    fputs(log_type, stream);
33    fputs("  ", stream);
34    vfprintf(stream, fmt, args);
35    fputs("\n", stream);
36 }
37
38 void lognotice(char const *fmt, ...) {
39    va_list a;
40    va_start(a, fmt);
41    log_("notice", stdout, fmt, a);
42    va_end(a);
43 }
44
45 void logerror(char const *fmt, ...) {
46    va_list a;
47    va_start(a, fmt);
48    log_("error", stderr, fmt, a);
49    va_end(a);
50 }
51
52 void fatal(char const *fmt, ...) {
53    va_list a;
54    va_start(a, fmt);
55    log_("fatal", stderr, fmt, a);
56    va_end(a);
57    abort();
58 }
59
60 #ifdef DEBUG_OUTPUT
61 void logdebug(char const *fmt, ...) {
62    va_list a;
63    va_start(a, fmt);
64    log_("debug", stdout, fmt, a);
65    va_end(a);
66 }
67 #endif
68
69 void Poller::add_fd(int fd, std::function<int(int)> handler) {
70    pfds.emplace_back(pollfd{.fd = fd, .events = POLLIN, .revents = 0});
71    handlers.emplace_back(std::move(handler));
72 }
73
74 int Poller::check_events() {
75    int ret = 0;
76    if ((ret = poll(this->pfds.data(), this->pfds.size(), -1)) != -1 &&
77        errno != EINTR) {
78       for (unsigned i = 0; i < pfds.size(); i++) {
79          if ((pfds[i].revents & POLLIN) != 0) {
80             if (handlers[i](pfds[i].fd) == -1) {
81                return -1;
82             }
83             pfds[i].revents = 0;
84             pfds[i].events = POLLIN;
85          }
86       }
87    }
88    return ret;
89 }
90
91 unique_fd::~unique_fd() {
92    if (this->fd != -1) {
93       close(this->fd);
94    }
95 }