X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fbasic%2Ftime-util.c;h=17d3da6fa296c5821300f2767907375f9dc201fb;hb=d76bb3c179b7a32b109e39aa87ff09c8f5a8c178;hp=e849ccc57d96841cc3822eeb6293630be941a55b;hpb=5db0e7adf018c82dd63cd21d31dd313dff5561af;p=elogind.git diff --git a/src/basic/time-util.c b/src/basic/time-util.c index e849ccc57..17d3da6fa 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -26,6 +26,7 @@ #include "util.h" #include "time-util.h" +#include "path-util.h" #include "strv.h" usec_t now(clockid_t clock_id) { @@ -36,6 +37,17 @@ usec_t now(clockid_t clock_id) { return timespec_load(&ts); } +/// UNNEEDED by elogind +#if 0 +nsec_t now_nsec(clockid_t clock_id) { + struct timespec ts; + + assert_se(clock_gettime(clock_id, &ts) == 0); + + return timespec_load_nsec(&ts); +} +#endif // 0 + dual_timestamp* dual_timestamp_get(dual_timestamp *ts) { assert(ts); @@ -89,6 +101,31 @@ dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) { return ts; } + +dual_timestamp* dual_timestamp_from_boottime_or_monotonic(dual_timestamp *ts, usec_t u) { + int64_t delta; + + if (u == USEC_INFINITY) { + ts->realtime = ts->monotonic = USEC_INFINITY; + return ts; + } + ts->realtime = now(CLOCK_REALTIME); + ts->monotonic = now(CLOCK_MONOTONIC); + + delta = (int64_t) now(clock_boottime_or_monotonic()) - (int64_t) u; + + if ((int64_t) ts->realtime > delta) + ts->realtime -= delta; + else + ts->realtime = 0; + + if ((int64_t) ts->monotonic > delta) + ts->monotonic -= delta; + else + ts->monotonic = 0; + + return ts; +} #endif // 0 usec_t timespec_load(const struct timespec *ts) { @@ -106,6 +143,18 @@ usec_t timespec_load(const struct timespec *ts) { (usec_t) ts->tv_nsec / NSEC_PER_USEC; } +nsec_t timespec_load_nsec(const struct timespec *ts) { + assert(ts); + + if (ts->tv_sec == (time_t) -1 && + ts->tv_nsec == (long) -1) + return NSEC_INFINITY; + + return + (nsec_t) ts->tv_sec * NSEC_PER_SEC + + (nsec_t) ts->tv_nsec; +} + struct timespec *timespec_store(struct timespec *ts, usec_t u) { assert(ts); @@ -751,6 +800,8 @@ int parse_sec(const char *t, usec_t *usec) { return 0; } +/// UNNEEDED by elogind +#if 0 int parse_nsec(const char *t, nsec_t *nsec) { static const struct { const char *suffix; @@ -876,8 +927,6 @@ int parse_nsec(const char *t, nsec_t *nsec) { return 0; } -/// UNNEEDED by elogind -#if 0 bool ntp_synced(void) { struct timex txc = {}; @@ -959,7 +1008,10 @@ bool timezone_is_valid(const char *name) { const char *p, *t; struct stat st; - if (!name || *name == 0 || *name == '/') + if (isempty(name)) + return false; + + if (name[0] == '/') return false; for (p = name; *p; p++) { @@ -1009,4 +1061,31 @@ clockid_t clock_boottime_or_monotonic(void) { return clock; } + +int get_timezone(char **tz) { + _cleanup_free_ char *t = NULL; + const char *e; + char *z; + int r; + + r = readlink_malloc("/etc/localtime", &t); + if (r < 0) + return r; /* returns EINVAL if not a symlink */ + + e = path_startswith(t, "/usr/share/zoneinfo/"); + if (!e) + e = path_startswith(t, "../usr/share/zoneinfo/"); + if (!e) + return -EINVAL; + + if (!timezone_is_valid(e)) + return -EINVAL; + + z = strdup(e); + if (!z) + return -ENOMEM; + + *tz = z; + return 0; +} #endif // 0