diff --git a/src/util.c b/src/util.c index fada69c..76c4de3 100644 --- a/src/util.c +++ b/src/util.c @@ -1960,13 +1960,11 @@ char *format_timespan(char *buf, size_t l, usec_t t) { { "d", USEC_PER_DAY }, { "h", USEC_PER_HOUR }, { "min", USEC_PER_MINUTE }, - { "s", USEC_PER_SEC }, - { "ms", USEC_PER_MSEC }, - { "us", 1 }, }; unsigned i; char *p = buf; + int k; assert(buf); assert(l > 0); @@ -1983,7 +1981,6 @@ char *format_timespan(char *buf, size_t l, usec_t t) { /* The result of this function can be parsed with parse_usec */ for (i = 0; i < ELEMENTSOF(table); i++) { - int k; size_t n; if (t < table[i].usec) @@ -2001,6 +1998,10 @@ char *format_timespan(char *buf, size_t l, usec_t t) { t %= table[i].usec; } + /* We have left a value between 0 and 59,999,999 (that is, 0s and 59.999999s) */ + k = snprintf(p, l, "%s%llu.%06llus", p > buf ? " " : "", (unsigned long long) (t / USEC_PER_SEC), (unsigned long long) (t % USEC_PER_SEC)); + p += MIN((size_t) k, l); + *p = 0; return buf; @@ -2638,6 +2639,7 @@ int parse_usec(const char *t, usec_t *usec) { } table[] = { { "sec", USEC_PER_SEC }, { "s", USEC_PER_SEC }, + { ".", USEC_PER_SEC }, { "min", USEC_PER_MINUTE }, { "hr", USEC_PER_HOUR }, { "h", USEC_PER_HOUR }, @@ -2651,6 +2653,17 @@ int parse_usec(const char *t, usec_t *usec) { { "", USEC_PER_SEC }, }; + static const usec_t fract[] = { + 0LL, + 1000000LL, + 100000LL, + 10000LL, + 1000LL, + 100LL, + 10LL, + 1LL + }; + const char *p; usec_t r = 0; @@ -2658,6 +2671,7 @@ int parse_usec(const char *t, usec_t *usec) { assert(usec); p = t; + char *seen_p = NULL; do { long long l; char *e; @@ -2679,7 +2693,13 @@ int parse_usec(const char *t, usec_t *usec) { for (i = 0; i < ELEMENTSOF(table); i++) if (startswith(e, table[i].suffix)) { - r += (usec_t) l * table[i].usec; + if (seen_p) { + if (*e != 's' || e - seen_p >= sizeof fract / sizeof fract[0]) + return -EINVAL; + r += (usec_t) l * fract[e - seen_p]; + } else + r += (usec_t) l * table[i].usec; + seen_p = table[i].suffix[0] == '.'? e: NULL; p = e + strlen(table[i].suffix); break; }