]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
src: replace gmtime_r/localtime_r/strftime with GDateTime
authorDaniel P. Berrangé <berrange@redhat.com>
Thu, 9 Jan 2020 14:07:15 +0000 (14:07 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Fri, 17 Jan 2020 10:02:01 +0000 (10:02 +0000)
gmtime_r/localtime_r are mostly used in combination with
strftime to format timestamps in libvirt. This can all
be replaced with GDateTime resulting in simpler code
that is also more portable.

There is some boundary condition problem in parsing POSIX
timezone offsets in GLib which tickles our test suite.
The test suite is hacked to avoid the problem. The upsteam
GLib bug report is

  https://gitlab.gnome.org/GNOME/glib/issues/1999

Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
14 files changed:
src/conf/domain_conf.c
src/libxl/libxl_domain.c
src/qemu/qemu_command.c
src/qemu/qemu_driver.c
src/util/virtime.c
tests/qemuxml2argvmock.c
tests/virtimetest.c
tools/virsh-checkpoint.c
tools/virsh-domain-monitor.c
tools/virsh-domain.c
tools/virsh-network.c
tools/virsh-snapshot.c
tools/virt-admin.c
tools/vsh.c

index e5bba9ed977fe61740e727644c620f492f39c080..f920d1dc3968e3821d39ef089c27ca6f7da0bbf3 100644 (file)
@@ -26790,11 +26790,12 @@ virDomainGraphicsAuthDefFormatAttr(virBufferPtr buf,
                               def->passwd);
 
     if (def->expires) {
-        char strbuf[100];
-        struct tm tmbuf, *tm;
-        tm = gmtime_r(&def->validTo, &tmbuf);
-        strftime(strbuf, sizeof(strbuf), "%Y-%m-%dT%H:%M:%S", tm);
-        virBufferAsprintf(buf, " passwdValidTo='%s'", strbuf);
+        g_autoptr(GDateTime) then = NULL;
+        g_autofree char *thenstr = NULL;
+
+        then = g_date_time_new_from_unix_utc(def->validTo);
+        thenstr = g_date_time_format(then, "%Y-%m-%dT%H:%M:%S");
+        virBufferAsprintf(buf, " passwdValidTo='%s'", thenstr);
     }
 
     if (def->connected)
index f9be4ad583409c890377668ae691bd073b26e03d..d63eca0bd66c56bddb466f88fdf33206d2fdffcf 100644 (file)
@@ -943,16 +943,14 @@ libxlDomainAutoCoreDump(libxlDriverPrivatePtr driver,
                         virDomainObjPtr vm)
 {
     g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver);
-    time_t curtime = time(NULL);
-    char timestr[100];
-    struct tm time_info;
+    g_autoptr(GDateTime) now = g_date_time_new_now_local();
+    g_autofree char *nowstr = NULL;
     char *dumpfile = NULL;
 
-    localtime_r(&curtime, &time_info);
-    strftime(timestr, sizeof(timestr), "%Y-%m-%d-%H:%M:%S", &time_info);
+    nowstr = g_date_time_format(now, "%Y-%m-%d-%H:%M:%S");
 
     dumpfile = g_strdup_printf("%s/%s-%s", cfg->autoDumpDir, vm->def->name,
-                               timestr);
+                               nowstr);
 
     /* Unlock virDomainObj while dumping core */
     virObjectUnlock(vm);
index eaed106a6d8f2333530f08dcf9d9e82cb36ca3d5..c66b60fd21b9f811d2962037e101763f75f876a8 100644 (file)
@@ -6070,8 +6070,9 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
         break;
 
     case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: {
-        time_t now = time(NULL);
-        struct tm nowbits;
+        g_autoptr(GDateTime) now = g_date_time_new_now_utc();
+        g_autoptr(GDateTime) then = NULL;
+        g_autofree char *thenstr = NULL;
 
         if (def->data.variable.basis == VIR_DOMAIN_CLOCK_BASIS_LOCALTIME) {
             long localOffset;
@@ -6094,8 +6095,8 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
             def->data.variable.basis = VIR_DOMAIN_CLOCK_BASIS_UTC;
         }
 
-        now += def->data.variable.adjustment;
-        gmtime_r(&now, &nowbits);
+        then = g_date_time_add_seconds(now, def->data.variable.adjustment);
+        thenstr = g_date_time_format(then, "%Y-%m-%dT%H:%M:%S");
 
         /* when an RTC_CHANGE event is received from qemu, we need to
          * have the adjustment used at domain start time available to
@@ -6105,13 +6106,7 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
         */
         def->data.variable.adjustment0 = def->data.variable.adjustment;
 
-        virBufferAsprintf(&buf, "base=%d-%02d-%02dT%02d:%02d:%02d",
-                          nowbits.tm_year + 1900,
-                          nowbits.tm_mon + 1,
-                          nowbits.tm_mday,
-                          nowbits.tm_hour,
-                          nowbits.tm_min,
-                          nowbits.tm_sec);
+        virBufferAsprintf(&buf, "base=%s", thenstr);
     }   break;
 
     default:
index 17104c4921c73279f6ed212ade1013e93730866d..7e379fe83a74401694a41f4909cd5319a86a57f7 100644 (file)
@@ -4090,9 +4090,8 @@ getAutoDumpPath(virQEMUDriverPtr driver,
                 virDomainObjPtr vm)
 {
     g_autofree char *domname = virDomainDefGetShortName(vm->def);
-    char timestr[100];
-    struct tm time_info;
-    time_t curtime = time(NULL);
+    g_autoptr(GDateTime) now = g_date_time_new_now_local();
+    g_autofree char *nowstr = NULL;
     g_autoptr(virQEMUDriverConfig) cfg = NULL;
 
     if (!domname)
@@ -4100,10 +4099,9 @@ getAutoDumpPath(virQEMUDriverPtr driver,
 
     cfg = virQEMUDriverGetConfig(driver);
 
-    localtime_r(&curtime, &time_info);
-    strftime(timestr, sizeof(timestr), "%Y-%m-%d-%H:%M:%S", &time_info);
+    nowstr = g_date_time_format(now, "%Y-%m-%d-%H:%M:%S");
 
-    return g_strdup_printf("%s/%s-%s", cfg->autoDumpPath, domname, timestr);
+    return g_strdup_printf("%s/%s-%s", cfg->autoDumpPath, domname, nowstr);
 }
 
 static void
index 13f899cb91e5be84ae56ea80b53b110b215f1cb0..bc8f06cd48738642a4eaaf0e094765cf192b226d 100644 (file)
@@ -302,8 +302,8 @@ char *virTimeStringThen(unsigned long long when)
 /**
  * virTimeLocalOffsetFromUTC:
  *
- * This function is threadsafe, but is *not* async signal safe (due to
- * gmtime_r() and mktime()).
+ * This function is threadsafe, but is *not* async signal safe
+ * due to use of GLib APIs.
  *
  * @offset: pointer to time_t that will be set to the difference
  *          between localtime and UTC in seconds (east of UTC is a
@@ -314,34 +314,11 @@ char *virTimeStringThen(unsigned long long when)
 int
 virTimeLocalOffsetFromUTC(long *offset)
 {
-    struct tm gmtimeinfo;
-    time_t current, utc;
+    g_autoptr(GDateTime) now = g_date_time_new_now_local();
+    GTimeSpan diff = g_date_time_get_utc_offset(now);
 
-    /* time() gives seconds since Epoch in current timezone */
-    if ((current = time(NULL)) == (time_t)-1) {
-        virReportSystemError(errno, "%s",
-                             _("failed to get current system time"));
-        return -1;
-    }
-
-    /* treat current as if it were in UTC */
-    if (!gmtime_r(&current, &gmtimeinfo)) {
-        virReportSystemError(errno, "%s",
-                             _("gmtime_r failed"));
-        return -1;
-    }
-
-    /* tell mktime to figure out itself whether or not DST is in effect */
-    gmtimeinfo.tm_isdst = -1;
-
-    /* mktime() also obeys current timezone rules */
-    if ((utc = mktime(&gmtimeinfo)) == (time_t)-1) {
-        virReportSystemError(errno, "%s",
-                             _("mktime failed"));
-        return -1;
-    }
-
-    *offset = current - utc;
+    /* GTimeSpan measures microseconds, we want seconds */
+    *offset = diff / 1000000;
     return 0;
 }
 
index 8143de16185777cd52dcb800e318394e7900053a..e5841bc8e338378226c6150a0a066a457fe7ecbb 100644 (file)
@@ -47,12 +47,14 @@ long virGetSystemPageSize(void)
     return 4096;
 }
 
-time_t time(time_t *t)
+GDateTime *g_date_time_new_now_utc(void)
 {
-    const time_t ret = 1234567890;
-    if (t)
-        *t = ret;
-    return ret;
+    return g_date_time_new_from_unix_utc(1234567890);
+}
+
+GDateTime *g_date_time_new_now_local(void)
+{
+    return g_date_time_new_from_unix_local(1234567890);
 }
 
 bool
index f8a81ff09066b7ea3544ba20b4ca29a9f3192afb..f9ac55192d1db18af0e0f92d8baeaeacfbd58cc7 100644 (file)
@@ -101,20 +101,12 @@ testTimeLocalOffset(const void *args)
 static bool
 isNearYearEnd(void)
 {
-    time_t current = time(NULL);
-    struct tm timeinfo;
+    g_autoptr(GDateTime) now = g_date_time_new_now_local();
 
-    if (current == (time_t)-1) {
-        VIR_DEBUG("time() failed");
-        return false;
-    }
-    if (!localtime_r(&current, &timeinfo)) {
-        VIR_DEBUG("localtime_r() failed");
-        return false;
-    }
-
-    return (timeinfo.tm_mon == 0 && timeinfo.tm_mday == 1) ||
-            (timeinfo.tm_mon == 11 && timeinfo.tm_mday == 31);
+    return ((g_date_time_get_month(now) == 1 &&
+             g_date_time_get_day_of_month(now) == 1) ||
+            (g_date_time_get_month(now) == 12 &&
+             g_date_time_get_day_of_month(now) == 31));
 }
 
 
@@ -186,14 +178,21 @@ mymain(void)
     /* test DST processing with timezones that always
      * have DST in effect; what's more, cover a zone with
      * with an unusual DST different than a usual one hour
+     *
+     * These tests originally used '0' as the first day,
+     * but changed to '1' due to GLib GTimeZone parsing bug:
+     *  https://gitlab.gnome.org/GNOME/glib/issues/1999
+     *
+     * Once we depend on a new enough GLib, we can put then
+     * back to 0 again.
      */
-    TEST_LOCALOFFSET("VIR-00:30VID,0/00:00:00,365/23:59:59",
+    TEST_LOCALOFFSET("VIR-00:30VID,1/00:00:00,364/23:59:59",
                      ((1 * 60) + 30) * 60);
-    TEST_LOCALOFFSET("VIR-02:30VID,0/00:00:00,365/23:59:59",
+    TEST_LOCALOFFSET("VIR-02:30VID,1/00:00:00,364/23:59:59",
                      ((3 * 60) + 30) * 60);
-    TEST_LOCALOFFSET("VIR-02:30VID-04:30,0/00:00:00,365/23:59:59",
+    TEST_LOCALOFFSET("VIR-02:30VID-04:30,1/00:00:00,364/23:59:59",
                      ((4 * 60) + 30) * 60);
-    TEST_LOCALOFFSET("VIR-12:00VID-13:00,0/00:00:00,365/23:59:59",
+    TEST_LOCALOFFSET("VIR-12:00VID-13:00,1/00:00:00,364/23:59:59",
                      ((13 * 60) +  0) * 60);
 
     if (!isNearYearEnd()) {
@@ -209,11 +208,11 @@ mymain(void)
          * tests, except on Dec 31 and Jan 1.
          */
 
-        TEST_LOCALOFFSET("VIR02:45VID00:45,0/00:00:00,365/23:59:59",
+        TEST_LOCALOFFSET("VIR02:45VID00:45,1/00:00:00,364/23:59:59",
                          -45 * 60);
-        TEST_LOCALOFFSET("VIR05:00VID04:00,0/00:00:00,365/23:59:59",
+        TEST_LOCALOFFSET("VIR05:00VID04:00,1/00:00:00,364/23:59:59",
                          ((-4 * 60) +  0) * 60);
-        TEST_LOCALOFFSET("VIR11:00VID10:00,0/00:00:00,365/23:59:59",
+        TEST_LOCALOFFSET("VIR11:00VID10:00,1/00:00:00,364/23:59:59",
                          ((-10 * 60) +  0) * 60);
     }
 
index f9749b5f6d0e8da8ec776b10f5a47287ce1eef1e..e82a67f075d90942d5b91f39f7fb2059c765e4d9 100644 (file)
@@ -719,9 +719,8 @@ cmdCheckpointList(vshControl *ctl,
     char *doc = NULL;
     virDomainCheckpointPtr checkpoint = NULL;
     long long creation_longlong;
-    time_t creation_time_t;
-    char timestr[100];
-    struct tm time_info;
+    g_autoptr(GDateTime) then = NULL;
+    g_autofree gchar *thenstr = NULL;
     bool tree = vshCommandOptBool(cmd, "tree");
     bool name = vshCommandOptBool(cmd, "name");
     bool from = vshCommandOptBool(cmd, "from");
@@ -835,21 +834,16 @@ cmdCheckpointList(vshControl *ctl,
         if (virXPathLongLong("string(/domaincheckpoint/creationTime)", ctxt,
                              &creation_longlong) < 0)
             continue;
-        creation_time_t = creation_longlong;
-        if (creation_time_t != creation_longlong) {
-            vshError(ctl, "%s", _("time_t overflow"));
-            continue;
-        }
-        localtime_r(&creation_time_t, &time_info);
-        strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S %z",
-                 &time_info);
+
+        then = g_date_time_new_from_unix_local(creation_longlong);
+        thenstr = g_date_time_format(then, "%Y-%m-%d %H:%M:%S %z");
 
         if (parent) {
-            if (vshTableRowAppend(table, chk_name, timestr,
+            if (vshTableRowAppend(table, chk_name, thenstr,
                                   NULLSTR_EMPTY(parent_chk), NULL) < 0)
                 goto cleanup;
         } else {
-            if (vshTableRowAppend(table, chk_name, timestr, NULL) < 0)
+            if (vshTableRowAppend(table, chk_name, thenstr, NULL) < 0)
                 goto cleanup;
         }
     }
index efcdc613c6f826d1fd7a82269386ac666c3d2832..933e2aa75fd4378286ab5f4a51b79104f1588c81 100644 (file)
@@ -1534,17 +1534,13 @@ cmdDomTime(vshControl *ctl, const vshCmd *cmd)
             goto cleanup;
 
         if (pretty) {
-            char timestr[100];
-            time_t cur_time = seconds;
-            struct tm time_info;
+            g_autoptr(GDateTime) then = NULL;
+            g_autofree char *thenstr = NULL;
 
-            if (!gmtime_r(&cur_time, &time_info)) {
-                vshError(ctl, _("Unable to format time"));
-                goto cleanup;
-            }
-            strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", &time_info);
+            then = g_date_time_new_from_unix_utc(seconds);
+            thenstr = g_date_time_format(then, "%Y-%m-%d %H:%M:%S");
 
-            vshPrint(ctl, _("Time: %s"), timestr);
+            vshPrint(ctl, _("Time: %s"), thenstr);
         } else {
             vshPrint(ctl, _("Time: %lld"), seconds);
         }
index c48575279cdd4e32b309a283badbdef673025c9a..e64e08e5da73d61067e53c02ee88ae1246a393ec 100644 (file)
@@ -5492,9 +5492,8 @@ static const vshCmdOptDef opts_screenshot[] = {
 static char *
 virshGenFileName(vshControl *ctl, virDomainPtr dom, const char *mime)
 {
-    char timestr[100];
-    time_t cur_time;
-    struct tm time_info;
+    g_autoptr(GDateTime) now = g_date_time_new_now_local();
+    g_autofree char *nowstr = NULL;
     const char *ext = NULL;
     char *ret = NULL;
 
@@ -5509,12 +5508,10 @@ virshGenFileName(vshControl *ctl, virDomainPtr dom, const char *mime)
         ext = ".png";
     /* add mime type here */
 
-    time(&cur_time);
-    localtime_r(&cur_time, &time_info);
-    strftime(timestr, sizeof(timestr), "%Y-%m-%d-%H:%M:%S", &time_info);
+    nowstr = g_date_time_format(now, "%Y-%m-%d-%H:%M:%S");
 
-    ret = g_strdup_printf("%s-%s%s", virDomainGetName(dom), timestr,
-                          NULLSTR_EMPTY(ext));
+    ret = g_strdup_printf("%s-%s%s", virDomainGetName(dom),
+                          nowstr, NULLSTR_EMPTY(ext));
 
     return ret;
 }
index a02c85fcb1181fce86328db3e366265be1a4b9fd..ed90736345e77fea1ec0f74f8a5cb85574e8cf9c 100644 (file)
@@ -1433,11 +1433,10 @@ cmdNetworkDHCPLeases(vshControl *ctl, const vshCmd *cmd)
         const char *typestr = NULL;
         g_autofree char *cidr_format = NULL;
         virNetworkDHCPLeasePtr lease = leases[i];
-        time_t expirytime_tmp = lease->expirytime;
-        struct tm ts;
-        char expirytime[32];
-        localtime_r(&expirytime_tmp, &ts);
-        strftime(expirytime, sizeof(expirytime), "%Y-%m-%d %H:%M:%S", &ts);
+        g_autoptr(GDateTime) then = g_date_time_new_from_unix_local(lease->expirytime);
+        g_autofree char *thenstr = NULL;
+
+        thenstr = g_date_time_format(then, "%Y-%m-%d %H:%M:%S");
 
         if (lease->type == VIR_IP_ADDR_TYPE_IPV4)
             typestr = "ipv4";
@@ -1447,7 +1446,7 @@ cmdNetworkDHCPLeases(vshControl *ctl, const vshCmd *cmd)
         cidr_format = g_strdup_printf("%s/%d", lease->ipaddr, lease->prefix);
 
         if (vshTableRowAppend(table,
-                              expirytime,
+                              thenstr,
                               NULLSTR_MINUS(lease->mac),
                               NULLSTR_MINUS(typestr),
                               NULLSTR_MINUS(cidr_format),
index a42397b42e999b336f5629c1eca5e9897532e97b..d5e68e4b1888d9f9a87ca27af52c73b03f4e40ee 100644 (file)
@@ -1492,9 +1492,8 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
     virDomainSnapshotPtr snapshot = NULL;
     char *state = NULL;
     long long creation_longlong;
-    time_t creation_time_t;
-    char timestr[100];
-    struct tm time_info;
+    g_autoptr(GDateTime) then = NULL;
+    g_autofree gchar *thenstr = NULL;
     bool tree = vshCommandOptBool(cmd, "tree");
     bool name = vshCommandOptBool(cmd, "name");
     bool from = vshCommandOptBool(cmd, "from");
@@ -1624,22 +1623,16 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
         if (virXPathLongLong("string(/domainsnapshot/creationTime)", ctxt,
                              &creation_longlong) < 0)
             continue;
-        creation_time_t = creation_longlong;
-        if (creation_time_t != creation_longlong) {
-            vshError(ctl, "%s", _("time_t overflow"));
-            continue;
-        }
-        localtime_r(&creation_time_t, &time_info);
-        strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S %z",
-                 &time_info);
+        then = g_date_time_new_from_unix_local(creation_longlong);
+        thenstr = g_date_time_format(then, "%Y-%m-%d %H:%M:%S %z");
 
         if (parent) {
-            if (vshTableRowAppend(table, snap_name, timestr, state,
+            if (vshTableRowAppend(table, snap_name, thenstr, state,
                                   NULLSTR_EMPTY(parent_snap),
                                   NULL) < 0)
                 goto cleanup;
         } else {
-            if (vshTableRowAppend(table, snap_name, timestr, state,
+            if (vshTableRowAppend(table, snap_name, thenstr, state,
                                   NULL) < 0)
                 goto cleanup;
         }
index 30106d1971f7800a224f1fa4de34e133391e5011..c71ebb10122bc63adca656f7d5faa55458be365c 100644 (file)
@@ -69,40 +69,6 @@ vshAdmClientTransportToString(int transport)
     return str ? _(str) : _("unknown");
 }
 
-/*
- * vshAdmGetTimeStr:
- *
- * Produces string representation (local time) of @then
- * (seconds since epoch UTC) using format 'YYYY-MM-DD HH:MM:SS+ZZZZ'.
- *
- * Returns 0 if conversion finished successfully, -1 in case of an error.
- * Caller is responsible for freeing the string returned.
- */
-static int
-vshAdmGetTimeStr(vshControl *ctl, time_t then, char **result)
-{
-    char *tmp = NULL;
-    struct tm timeinfo;
-
-    if (!localtime_r(&then, &timeinfo))
-        goto error;
-
-    if (VIR_ALLOC_N(tmp, VIRT_ADMIN_TIME_BUFLEN) < 0)
-        goto error;
-
-    if (strftime(tmp, VIRT_ADMIN_TIME_BUFLEN, "%Y-%m-%d %H:%M:%S%z",
-                 &timeinfo) == 0) {
-        VIR_FREE(tmp);
-        goto error;
-    }
-
-    *result = tmp;
-    return 0;
-
- error:
-    vshError(ctl, "%s", _("Timestamp string conversion failed"));
-    return -1;
-}
 
 /*
  * vshAdmCatchDisconnect:
@@ -646,19 +612,19 @@ cmdSrvClientsList(vshControl *ctl, const vshCmd *cmd)
         goto cleanup;
 
     for (i = 0; i < nclts; i++) {
-        g_autofree char *timestr = NULL;
+        g_autoptr(GDateTime) then = NULL;
+        g_autofree gchar *thenstr = NULL;
         g_autofree char *idStr = NULL;
         virAdmClientPtr client = clts[i];
         id = virAdmClientGetID(client);
+        then = g_date_time_new_from_unix_local(virAdmClientGetTimestamp(client));
         transport = virAdmClientGetTransport(client);
-        if (vshAdmGetTimeStr(ctl, virAdmClientGetTimestamp(client),
-                             &timestr) < 0)
-            goto cleanup;
 
+        thenstr = g_date_time_format(then,  "%Y-%m-%d %H:%M:%S%z");
         idStr = g_strdup_printf("%llu", id);
         if (vshTableRowAppend(table, idStr,
                               vshAdmClientTransportToString(transport),
-                              timestr, NULL) < 0)
+                              thenstr, NULL) < 0)
             goto cleanup;
     }
 
@@ -714,7 +680,8 @@ cmdClientInfo(vshControl *ctl, const vshCmd *cmd)
     size_t i;
     unsigned long long id;
     const char *srvname = NULL;
-    char *timestr = NULL;
+    g_autoptr(GDateTime) then = NULL;
+    g_autofree gchar *thenstr = NULL;
     virAdmServerPtr srv = NULL;
     virAdmClientPtr clnt = NULL;
     virTypedParameterPtr params = NULL;
@@ -739,12 +706,13 @@ cmdClientInfo(vshControl *ctl, const vshCmd *cmd)
         goto cleanup;
     }
 
-    if (vshAdmGetTimeStr(ctl, virAdmClientGetTimestamp(clnt), &timestr) < 0)
-        goto cleanup;
+
+    then = g_date_time_new_from_unix_local(virAdmClientGetTimestamp(clnt));
+    thenstr = g_date_time_format(then,  "%Y-%m-%d %H:%M:%S%z");
 
     /* this info is provided by the client object itself */
     vshPrint(ctl, "%-15s: %llu\n", "id", virAdmClientGetID(clnt));
-    vshPrint(ctl, "%-15s: %s\n", "connection_time", timestr);
+    vshPrint(ctl, "%-15s: %s\n", "connection_time", thenstr);
     vshPrint(ctl, "%-15s: %s\n", "transport",
              vshAdmClientTransportToString(virAdmClientGetTransport(clnt)));
 
@@ -760,7 +728,6 @@ cmdClientInfo(vshControl *ctl, const vshCmd *cmd)
     virTypedParamsFree(params, nparams);
     virAdmServerFree(srv);
     virAdmClientFree(clnt);
-    VIR_FREE(timestr);
     return ret;
 }
 
index 5c8908f2409114ae036ce8d47d2ed82f3ce5f361..949c8dad7b331f1b98873180b5a5c496a0f08773 100644 (file)
@@ -2182,8 +2182,8 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format,
     char *str = NULL;
     size_t len;
     const char *lvl = "";
-    time_t stTime;
-    struct tm stTm;
+    g_autoptr(GDateTime) now = g_date_time_new_now_local();
+    g_autofree gchar *nowstr = NULL;
 
     if (ctl->log_fd == -1)
         return;
@@ -2193,15 +2193,9 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format,
      *
      * [YYYY.MM.DD HH:MM:SS SIGNATURE PID] LOG_LEVEL message
     */
-    time(&stTime);
-    localtime_r(&stTime, &stTm);
-    virBufferAsprintf(&buf, "[%d.%02d.%02d %02d:%02d:%02d %s %d] ",
-                      (1900 + stTm.tm_year),
-                      (1 + stTm.tm_mon),
-                      stTm.tm_mday,
-                      stTm.tm_hour,
-                      stTm.tm_min,
-                      stTm.tm_sec,
+    nowstr = g_date_time_format(now, "%Y.%m.%d %H:%M:%S");
+    virBufferAsprintf(&buf, "[%s %s %d] ",
+                      nowstr,
                       ctl->progname,
                       (int) getpid());
     switch (log_level) {