#include "rbar.h" #include /* uint64_t */ #include /* atexit(3p) */ #include #include /* glock_gettime, localtime, strftime */ const char *cleanup_id; void strfree(char **strp) { free(*strp); } void cleanup(void) { char __attribute__((__cleanup__(strfree))) *glob_id = rbar_globescape(cleanup_id); rbar_remove(glob_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"); rbar_write(id, str); } } struct impl impl = { .update = update, };