diff options
Diffstat (limited to '.config/wmii-hg/rbar_clock.c')
-rw-r--r-- | .config/wmii-hg/rbar_clock.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/.config/wmii-hg/rbar_clock.c b/.config/wmii-hg/rbar_clock.c new file mode 100644 index 0000000..ab636c2 --- /dev/null +++ b/.config/wmii-hg/rbar_clock.c @@ -0,0 +1,56 @@ +#include "rbar.h" + +#include <stdint.h> /* uint64_t */ +#include <stdlib.h> /* atexit(3p) */ +#include <sys/timerfd.h> +#include <time.h> /* glock_gettime, localtime, strftime */ + +const char *cleanup_id; + +void cleanup(void) { + rbar_remove(rbar_globescape(cleanup_id)); +} + +int update(const char *id) { + cleanup_id = id; + atexit(cleanup); + + int timer = timerfd_create(CLOCK_REALTIME, 0); + if (timer < 0) + error(1, errno, "timerfd_create"); + + struct timespec now; + if (clock_gettime(CLOCK_REALTIME, &now) < 0) + error(1, errno, "clock_gettime"); + + struct itimerspec spec = { + .it_interval = (struct timespec){.tv_sec = 1, .tv_nsec = 0}, + .it_value = (struct timespec){.tv_sec = now.tv_sec+1, .tv_nsec = 0}, + }; + + if (timerfd_settime(timer, TFD_TIMER_ABSTIME, &spec, NULL) < 0) + error(1, errno, "timerfd_settime"); + + for (;;) { + uint64_t count; + if (read(timer, &count, sizeof count) != sizeof count) + error(1, errno, "read"); + if (clock_gettime(CLOCK_REALTIME, &now) < 0) + error(1, errno, "clock_gettime"); + char str[80]; + if (strftime(str, sizeof str, + "label %a %F %T %Z(%z)", /* apparently %:::z" is supported by date(1gnu) but not strftime(3gnu) */ + localtime(&now.tv_sec)) <= 0) + error(1, 0, "strftime wanted a really long string"); + int err = rbar_write(id, str); + if (err != 0) { + if (err == GLOB_NOMATCH) + return 0; + return 1; + } + } +} + +struct impl impl = { + .update = update, +}; |