X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Ftime-util.c;h=1c36c577c4af36c9255554831161c8e65cb26171;hp=066ef973ac88d64e4a512d9743b03aca9534c53f;hb=2f07de3b6cacf44462635ab0fff56391b491e454;hpb=b1d6dcf5a5c5aa02843c026dede0638f77798cb4 diff --git a/src/shared/time-util.c b/src/shared/time-util.c index 066ef973a..1c36c577c 100644 --- a/src/shared/time-util.c +++ b/src/shared/time-util.c @@ -49,25 +49,20 @@ dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) { int64_t delta; assert(ts); - if (u == USEC_INFINITY) { - ts->realtime = ts->monotonic = USEC_INFINITY; + if (u == USEC_INFINITY || u <= 0) { + ts->realtime = ts->monotonic = u; return ts; } ts->realtime = u; - if (u == 0) - ts->monotonic = 0; - else { - delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u; - - ts->monotonic = now(CLOCK_MONOTONIC); + delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u; + ts->monotonic = now(CLOCK_MONOTONIC); - if ((int64_t) ts->monotonic > delta) - ts->monotonic -= delta; - else - ts->monotonic = 0; - } + if ((int64_t) ts->monotonic > delta) + ts->monotonic -= delta; + else + ts->monotonic = 0; return ts; } @@ -152,7 +147,7 @@ struct timeval *timeval_store(struct timeval *tv, usec_t u) { return tv; } -char *format_timestamp(char *buf, size_t l, usec_t t) { +static char *format_timestamp_internal(char *buf, size_t l, usec_t t, bool utc) { struct tm tm; time_t sec; @@ -164,13 +159,25 @@ char *format_timestamp(char *buf, size_t l, usec_t t) { sec = (time_t) (t / USEC_PER_SEC); - if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm)) <= 0) + if (utc) + gmtime_r(&sec, &tm); + else + localtime_r(&sec, &tm); + if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S %Z", &tm) <= 0) return NULL; return buf; } -char *format_timestamp_us(char *buf, size_t l, usec_t t) { +char *format_timestamp(char *buf, size_t l, usec_t t) { + return format_timestamp_internal(buf, l, t, false); +} + +char *format_timestamp_utc(char *buf, size_t l, usec_t t) { + return format_timestamp_internal(buf, l, t, true); +} + +static char *format_timestamp_internal_us(char *buf, size_t l, usec_t t, bool utc) { struct tm tm; time_t sec; @@ -181,7 +188,10 @@ char *format_timestamp_us(char *buf, size_t l, usec_t t) { return NULL; sec = (time_t) (t / USEC_PER_SEC); - localtime_r(&sec, &tm); + if (utc) + gmtime_r(&sec, &tm); + else + localtime_r(&sec, &tm); if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S", &tm) <= 0) return NULL; @@ -192,15 +202,22 @@ char *format_timestamp_us(char *buf, size_t l, usec_t t) { return buf; } +char *format_timestamp_us(char *buf, size_t l, usec_t t) { + return format_timestamp_internal_us(buf, l, t, false); +} + +char *format_timestamp_us_utc(char *buf, size_t l, usec_t t) { + return format_timestamp_internal_us(buf, l, t, true); +} + char *format_timestamp_relative(char *buf, size_t l, usec_t t) { const char *s; usec_t n, d; - n = now(CLOCK_REALTIME); - - if (t <= 0 || (t == USEC_INFINITY)) + if (t <= 0 || t == USEC_INFINITY) return NULL; + n = now(CLOCK_REALTIME); if (n > t) { d = n - t; s = "ago"; @@ -279,8 +296,14 @@ char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) { assert(buf); assert(l > 0); - if (t == USEC_INFINITY || t <= 0) { - strncpy(p, t == USEC_INFINITY ? "infinity" : "0", l); + if (t == USEC_INFINITY) { + strncpy(p, "infinity", l-1); + p[l-1] = 0; + return p; + } + + if (t <= 0) { + strncpy(p, "0", l-1); p[l-1] = 0; return p; } @@ -750,7 +773,7 @@ int parse_nsec(const char *t, nsec_t *nsec) { { "", 1ULL }, /* default is nsec */ }; - const char *p; + const char *p, *s; nsec_t r = 0; bool something = false; @@ -758,6 +781,18 @@ int parse_nsec(const char *t, nsec_t *nsec) { assert(nsec); p = t; + + p += strspn(p, WHITESPACE); + s = startswith(p, "infinity"); + if (s) { + s += strspn(s, WHITESPACE); + if (*s != 0) + return -EINVAL; + + *nsec = NSEC_INFINITY; + return 0; + } + for (;;) { long long l, z = 0; char *e; @@ -930,7 +965,7 @@ bool timezone_is_valid(const char *name) { if (slash) return false; - t = strappenda("/usr/share/zoneinfo/", name); + t = strjoina("/usr/share/zoneinfo/", name); if (stat(t, &st) < 0) return false;