]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/timeutils: implement nanosecond formatting
authorThomas Weißschuh <thomas@t-8ch.de>
Tue, 27 Jun 2023 06:53:56 +0000 (08:53 +0200)
committerThomas Weißschuh <thomas@t-8ch.de>
Wed, 28 Jun 2023 12:58:06 +0000 (14:58 +0200)
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
include/timeutils.h
lib/timeutils.c

index 88b547c7207eaafe42ac73ab59e0be28286df184..f0a75a4a86c42f02971624e024478805cfe47d46 100644 (file)
@@ -57,8 +57,10 @@ enum {
        ISO_TIMEZONE            = (1 << 2),
        ISO_DOTUSEC             = (1 << 3),
        ISO_COMMAUSEC           = (1 << 4),
-       ISO_T                   = (1 << 5),
-       ISO_GMTIME              = (1 << 6),
+       ISO_DOTNSEC             = (1 << 5),
+       ISO_COMMANSEC           = (1 << 6),
+       ISO_T                   = (1 << 7),
+       ISO_GMTIME              = (1 << 8),
        ISO_TIMESTAMP           = ISO_DATE | ISO_TIME | ISO_TIMEZONE,
        ISO_TIMESTAMP_T         = ISO_TIMESTAMP | ISO_T,
        ISO_TIMESTAMP_DOT       = ISO_TIMESTAMP | ISO_DOTUSEC,
index 1dafd9d638c202288008ad9849e81310a97e086f..7cf0f76521a4af377e4c116bd2a48431a7768635 100644 (file)
@@ -448,8 +448,9 @@ int get_gmtoff(const struct tm *tp)
 #endif
 }
 
-static int format_iso_time(const struct tm *tm, suseconds_t usec, int flags, char *buf, size_t bufsz)
+static int format_iso_time(const struct tm *tm, uint32_t nsec, int flags, char *buf, size_t bufsz)
 {
+       uint32_t usec = nsec / NSEC_PER_USEC;
        char *p = buf;
        int len;
 
@@ -479,15 +480,28 @@ static int format_iso_time(const struct tm *tm, suseconds_t usec, int flags, cha
                p += len;
        }
 
-       if (flags & ISO_DOTUSEC) {
-               len = snprintf(p, bufsz, ".%06"PRId64, (int64_t) usec);
+       if (flags & ISO_DOTNSEC) {
+               len = snprintf(p, bufsz, ".%09"PRIu32, nsec);
+               if (len < 0 || (size_t) len > bufsz)
+                       goto err;
+               bufsz -= len;
+               p += len;
+
+       } else if (flags & ISO_COMMANSEC) {
+               len = snprintf(p, bufsz, ",%09"PRIu32, nsec);
+               if (len < 0 || (size_t) len > bufsz)
+                       goto err;
+               bufsz -= len;
+               p += len;
+       } else if (flags & ISO_DOTUSEC) {
+               len = snprintf(p, bufsz, ".%06"PRIu32, usec);
                if (len < 0 || (size_t) len > bufsz)
                        goto err;
                bufsz -= len;
                p += len;
 
        } else if (flags & ISO_COMMAUSEC) {
-               len = snprintf(p, bufsz, ",%06"PRId64, (int64_t) usec);
+               len = snprintf(p, bufsz, ",%06"PRIu32, usec);
                if (len < 0 || (size_t) len > bufsz)
                        goto err;
                bufsz -= len;
@@ -520,7 +534,7 @@ int strtimeval_iso(const struct timeval *tv, int flags, char *buf, size_t bufsz)
                rc = localtime_r(&tv->tv_sec, &tm);
 
        if (rc)
-               return format_iso_time(&tm, tv->tv_usec, flags, buf, bufsz);
+               return format_iso_time(&tm, tv->tv_usec * NSEC_PER_USEC, flags, buf, bufsz);
 
        warnx(_("time %"PRId64" is out of range."), (int64_t)(tv->tv_sec));
        return -1;