diff options
Diffstat (limited to 'src/libudev')
-rw-r--r-- | src/libudev/missing.h | 2 | ||||
-rw-r--r-- | src/libudev/util.c | 107 | ||||
-rw-r--r-- | src/libudev/util.h | 1 |
3 files changed, 109 insertions, 1 deletions
diff --git a/src/libudev/missing.h b/src/libudev/missing.h index aa578d1fe0..a2ca518948 100644 --- a/src/libudev/missing.h +++ b/src/libudev/missing.h @@ -139,7 +139,7 @@ static inline int fanotify_init(unsigned int flags, unsigned int event_f_flags) static inline int fanotify_mark(int fanotify_fd, unsigned int flags, uint64_t mask, int dfd, const char *pathname) { #if defined _MIPS_SIM && _MIPS_SIM == _MIPS_SIM_ABI32 || defined __powerpc__ && !defined __powerpc64__ \ - || defined __arm__ && !defined __aarch64__ + || defined __arm__ && !defined __aarch64__ union { uint64_t _64; uint32_t _32[2]; diff --git a/src/libudev/util.c b/src/libudev/util.c index e447f89647..f625cfe99b 100644 --- a/src/libudev/util.c +++ b/src/libudev/util.c @@ -127,6 +127,113 @@ usec_t timespec_load(const struct timespec *ts) { (usec_t) ts->tv_nsec / NSEC_PER_USEC; } +char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) { + static const struct { + const char *suffix; + usec_t usec; + } table[] = { + { "y", USEC_PER_YEAR }, + { "month", USEC_PER_MONTH }, + { "w", USEC_PER_WEEK }, + { "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; + bool something = false; + + assert(buf); + assert(l > 0); + + if (t == (usec_t) -1) + return NULL; + + if (t <= 0) { + snprintf(p, l, "0"); + p[l-1] = 0; + return p; + } + + /* The result of this function can be parsed with parse_sec */ + + for (i = 0; i < ELEMENTSOF(table); i++) { + int k; + size_t n; + bool done = false; + usec_t a, b; + + if (t <= 0) + break; + + if (t < accuracy && something) + break; + + if (t < table[i].usec) + continue; + + if (l <= 1) + break; + + a = t / table[i].usec; + b = t % table[i].usec; + + /* Let's see if we should shows this in dot notation */ + if (t < USEC_PER_MINUTE && b > 0) { + usec_t cc; + int j; + + j = 0; + for (cc = table[i].usec; cc > 1; cc /= 10) + j++; + + for (cc = accuracy; cc > 1; cc /= 10) { + b /= 10; + j--; + } + + if (j > 0) { + k = snprintf(p, l, + "%s%llu.%0*llu%s", + p > buf ? " " : "", + (unsigned long long) a, + j, + (unsigned long long) b, + table[i].suffix); + + t = 0; + done = true; + } + } + + /* No? Then let's show it normally */ + if (!done) { + k = snprintf(p, l, + "%s%llu%s", + p > buf ? " " : "", + (unsigned long long) a, + table[i].suffix); + + t = b; + } + + n = MIN((size_t) k, l); + + l -= n; + p += n; + + something = true; + } + + *p = 0; + + return buf; +} + char* endswith(const char *s, const char *postfix) { size_t sl, pl; diff --git a/src/libudev/util.h b/src/libudev/util.h index 2ac6f59c49..60b300da3c 100644 --- a/src/libudev/util.h +++ b/src/libudev/util.h @@ -84,6 +84,7 @@ union dirent_storage { usec_t now(clockid_t clock); usec_t timespec_load(const struct timespec *ts); +char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy); size_t page_size(void); #define PAGE_ALIGN(l) ALIGN_TO((l), page_size()) |