[libvirt] [PATCH] build: use re-entrant functions in virsh

Eric Blake eblake at redhat.com
Tue Sep 4 23:36:34 UTC 2012


Today's patches pointed out that virsh was still using localtime(),
which is not thread-safe, even though virsh is definitely
multi-threaded.

* cfg.mk (exclude_file_name_regexp--sc_prohibit_nonreentrant):
Tighten the rule.
* tools/virsh.c (vshOutputLogFile): Avoid localtime.
(vshEditWriteToTempFile, vshEditReadBackFile, cmdCd, cmdPwd)
(vshCloseLogFile): Avoid strerror.
* tools/console.c (vshMakeStdinRaw): Likewise.
* tools/virsh-domain.c (vshGenFileName): Fix spacing in previous
patch.
---
 cfg.mk               |  2 +-
 tools/console.c      | 11 +++++++----
 tools/virsh-domain.c |  2 +-
 tools/virsh.c        | 40 ++++++++++++++++++++++++----------------
 4 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/cfg.mk b/cfg.mk
index 4cdfd1b..245e0f2 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -780,7 +780,7 @@ exclude_file_name_regexp--sc_prohibit_newline_at_end_of_diagnostic = \
   ^src/rpc/gendispatch\.pl$$

 exclude_file_name_regexp--sc_prohibit_nonreentrant = \
-  ^((po|tests)/|docs/.*py$$|tools/(virsh|console)\.c$$)
+  ^((po|tests)/|docs/.*py$$)

 exclude_file_name_regexp--sc_prohibit_raw_allocation = \
   ^(src/util/memory\.[ch]|examples/.*)$$
diff --git a/tools/console.c b/tools/console.c
index fee2ce3..4394e48 100644
--- a/tools/console.c
+++ b/tools/console.c
@@ -1,7 +1,7 @@
 /*
  * console.c: A dumb serial console client
  *
- * Copyright (C) 2007-2008, 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2007-2008, 2010-2012 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -299,13 +299,16 @@ vshGetEscapeChar(const char *s)
     return *s;
 }

-int vshMakeStdinRaw(struct termios *ttyattr, bool report_errors) {
+int
+vshMakeStdinRaw(struct termios *ttyattr, bool report_errors)
+{
     struct termios rawattr;
+    char ebuf[1024];

     if (tcgetattr(STDIN_FILENO, ttyattr) < 0) {
         if (report_errors)
             VIR_ERROR(_("unable to get tty attributes: %s"),
-                      strerror(errno));
+                      virStrerror(errno, ebuf, sizeof(ebuf)));
         return -1;
     }

@@ -315,7 +318,7 @@ int vshMakeStdinRaw(struct termios *ttyattr, bool report_errors) {
     if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &rawattr) < 0) {
         if (report_errors)
             VIR_ERROR(_("unable to set tty attributes: %s"),
-                      strerror(errno));
+                      virStrerror(errno, ebuf, sizeof(ebuf)));
         return -1;
     }

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 3cef782..727c39b 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -3723,7 +3723,7 @@ vshGenFileName(vshControl *ctl, virDomainPtr dom, const char *mime)
         ext = ".png";
     /* add mime type here */

-    time (&cur_time);
+    time(&cur_time);
     localtime_r(&cur_time, &time_info);
     strftime(timestr, sizeof(timestr), "%Y-%m-%d-%H:%M:%S", &time_info);

diff --git a/tools/virsh.c b/tools/virsh.c
index 88da429..e3f9e4e 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -511,6 +511,7 @@ vshEditWriteToTempFile(vshControl *ctl, const char *doc)
     char *ret;
     const char *tmpdir;
     int fd;
+    char ebuf[1024];

     tmpdir = getenv ("TMPDIR");
     if (!tmpdir) tmpdir = "/tmp";
@@ -521,14 +522,14 @@ vshEditWriteToTempFile(vshControl *ctl, const char *doc)
     fd = mkstemps(ret, 4);
     if (fd == -1) {
         vshError(ctl, _("mkstemps: failed to create temporary file: %s"),
-                 strerror(errno));
+                 virStrerror(errno, ebuf, sizeof(ebuf)));
         VIR_FREE(ret);
         return NULL;
     }

     if (safewrite(fd, doc, strlen(doc)) == -1) {
         vshError(ctl, _("write: %s: failed to write to temporary file: %s"),
-                 ret, strerror(errno));
+                 ret, virStrerror(errno, ebuf, sizeof(ebuf)));
         VIR_FORCE_CLOSE(fd);
         unlink(ret);
         VIR_FREE(ret);
@@ -536,7 +537,7 @@ vshEditWriteToTempFile(vshControl *ctl, const char *doc)
     }
     if (VIR_CLOSE(fd) < 0) {
         vshError(ctl, _("close: %s: failed to write or close temporary file: %s"),
-                 ret, strerror(errno));
+                 ret, virStrerror(errno, ebuf, sizeof(ebuf)));
         unlink(ret);
         VIR_FREE(ret);
         return NULL;
@@ -606,11 +607,12 @@ char *
 vshEditReadBackFile(vshControl *ctl, const char *filename)
 {
     char *ret;
+    char ebuf[1024];

     if (virFileReadAll(filename, VSH_MAX_XML_FILE, &ret) == -1) {
         vshError(ctl,
                  _("%s: failed to read temporary file: %s"),
-                 filename, strerror(errno));
+                 filename, virStrerror(errno, ebuf, sizeof(ebuf)));
         return NULL;
     }
     return ret;
@@ -637,6 +639,7 @@ cmdCd(vshControl *ctl, const vshCmd *cmd)
     const char *dir = NULL;
     char *dir_malloced = NULL;
     bool ret = true;
+    char ebuf[1024];

     if (!ctl->imode) {
         vshError(ctl, "%s", _("cd: command valid only in interactive mode"));
@@ -650,7 +653,8 @@ cmdCd(vshControl *ctl, const vshCmd *cmd)
         dir = "/";

     if (chdir(dir) == -1) {
-        vshError(ctl, _("cd: %s: %s"), strerror(errno), dir);
+        vshError(ctl, _("cd: %s: %s"),
+                 virStrerror(errno, ebuf, sizeof(ebuf)), dir);
         ret = false;
     }

@@ -672,11 +676,12 @@ cmdPwd(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
 {
     char *cwd;
     bool ret = true;
+    char ebuf[1024];

     cwd = getcwd(NULL, 0);
     if (!cwd) {
         vshError(ctl, _("pwd: cannot get current directory: %s"),
-                 strerror(errno));
+                 virStrerror(errno, ebuf, sizeof(ebuf)));
         ret = false;
     } else {
         vshPrint(ctl, _("%s\n"), cwd);
@@ -2188,7 +2193,7 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format,
     size_t len;
     const char *lvl = "";
     time_t stTime;
-    struct tm *stTm;
+    struct tm stTm;

     if (ctl->log_fd == -1)
         return;
@@ -2198,15 +2203,15 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format,
      *
      * [YYYY.MM.DD HH:MM:SS SIGNATURE PID] LOG_LEVEL message
     */
-    time (&stTime);
-    stTm = localtime(&stTime);
+    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,
+                      (1900 + stTm.tm_year),
+                      (1 + stTm.tm_mon),
+                      stTm.tm_mday,
+                      stTm.tm_hour,
+                      stTm.tm_min,
+                      stTm.tm_sec,
                       SIGN_NAME,
                       (int) getpid());
     switch (log_level) {
@@ -2264,10 +2269,13 @@ error:
 void
 vshCloseLogFile(vshControl *ctl)
 {
+    char ebuf[1024];
+
     /* log file close */
     if (VIR_CLOSE(ctl->log_fd) < 0) {
         vshError(ctl, _("%s: failed to write log file: %s"),
-                 ctl->logfile ? ctl->logfile : "?", strerror (errno));
+                 ctl->logfile ? ctl->logfile : "?",
+                 virStrerror(errno, ebuf, sizeof(ebuf)));
     }

     if (ctl->logfile) {
-- 
1.7.11.4




More information about the libvir-list mailing list