/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See the file COPYING * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Copyright (C) 2017 Frank van Maarseveen */ #include #include #include #include #include #include #include #include #include "common.h" const char * me; int opt_v; const struct timespec TS_TIMESPEC_ZERO; void out(const char *fmt, ...) { va_list ap; if (opt_v) { va_start(ap, fmt); vfprintf(stdout, fmt, ap); fflush(stdout); va_end(ap); } } void err(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); } void die(const char *fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s: ", me); vfprintf(stderr, fmt, ap); va_end(ap); exit(1); } void *new(size_t size) { void *mem; mem = calloc(1, size); if (!mem) die("out of memory.\n"); return mem; } char *newstr(const char *s) { return strcpy(new(strlen(s) + 1), s); } char *strip(char *p) { char *q; while (isspace(*p)) ++p; q = p + strlen(p); while (q > p && isspace(q[-1])) --q; *q = 0; return p; } /* * Return YYYY/mm/dd HH:MM:SS representation of the given time_t. The returned * buffer will be reused on the next call. */ const char *time2str(time_t t) { struct tm *tm; static char buf[32]; /* 20 should do */ tm = localtime(&t); strftime(buf, sizeof (buf) - 1, "%Y/%m/%d %H:%M:%S", tm); buf[sizeof (buf) - 1] = 0; return buf; } struct timespec ts_get(const struct timespec *epoch) { struct timespec t; if (clock_gettime(CLOCK_MONOTONIC_RAW, &t) == -1) die("clock_gettime: %s\n", strerror(errno)); if (t.tv_nsec < 0 || t.tv_nsec >= 1000000000) err("clock_gettime: tv_nsec=%ld!\n", t.tv_nsec); if (epoch) ts_sub(&t, epoch); return t; } void ts_add(struct timespec *t1, const struct timespec *t2) { t1->tv_sec += t2->tv_sec; t1->tv_nsec += t2->tv_nsec; if (t1->tv_nsec >= 1000000000) { t1->tv_nsec -= 1000000000; ++t1->tv_sec; } } void ts_addns(struct timespec *t, long ns) { long s; if (ns < 0 || ns >= 1000000000) { s = ns / 1000000000; ns %= 1000000000; if (ns < 0) { ns += 1000000000; --s; } t->tv_sec += s; } t->tv_nsec += ns; if (t->tv_nsec >= 1000000000) { t->tv_nsec -= 1000000000; ++t->tv_sec; } } void ts_sub(struct timespec *t1, const struct timespec *t2) { t1->tv_sec -= t2->tv_sec; t1->tv_nsec -= t2->tv_nsec; if (t1->tv_nsec < 0) { t1->tv_nsec += 1000000000; --t1->tv_sec; } } bool_t ts_after(const struct timespec *t1, const struct timespec *t2) { return t1->tv_sec > t2->tv_sec || (t1->tv_sec == t2->tv_sec && t1->tv_nsec > t2->tv_nsec); }