build: use re-entrant functions in virsh

Yesterday's commit 15d2c9f pointed out that virsh was still using
localtime(), which is not thread-safe, even though virsh is
definitely multi-threaded.  Even if we only ever triggered it from
one thread, it's better safe than sorry for maintenance purposes.

* 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.
This commit is contained in:
Eric Blake 2012-09-04 17:35:27 -06:00
parent 8386b304b0
commit 44342a0efe
4 changed files with 33 additions and 22 deletions

2
cfg.mk
View File

@ -780,7 +780,7 @@ exclude_file_name_regexp--sc_prohibit_newline_at_end_of_diagnostic = \
^src/rpc/gendispatch\.pl$$ ^src/rpc/gendispatch\.pl$$
exclude_file_name_regexp--sc_prohibit_nonreentrant = \ 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 = \ exclude_file_name_regexp--sc_prohibit_raw_allocation = \
^(src/util/memory\.[ch]|examples/.*)$$ ^(src/util/memory\.[ch]|examples/.*)$$

View File

@ -1,7 +1,7 @@
/* /*
* console.c: A dumb serial console client * 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 * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -299,13 +299,16 @@ vshGetEscapeChar(const char *s)
return *s; return *s;
} }
int vshMakeStdinRaw(struct termios *ttyattr, bool report_errors) { int
vshMakeStdinRaw(struct termios *ttyattr, bool report_errors)
{
struct termios rawattr; struct termios rawattr;
char ebuf[1024];
if (tcgetattr(STDIN_FILENO, ttyattr) < 0) { if (tcgetattr(STDIN_FILENO, ttyattr) < 0) {
if (report_errors) if (report_errors)
VIR_ERROR(_("unable to get tty attributes: %s"), VIR_ERROR(_("unable to get tty attributes: %s"),
strerror(errno)); virStrerror(errno, ebuf, sizeof(ebuf)));
return -1; return -1;
} }
@ -315,7 +318,7 @@ int vshMakeStdinRaw(struct termios *ttyattr, bool report_errors) {
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &rawattr) < 0) { if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &rawattr) < 0) {
if (report_errors) if (report_errors)
VIR_ERROR(_("unable to set tty attributes: %s"), VIR_ERROR(_("unable to set tty attributes: %s"),
strerror(errno)); virStrerror(errno, ebuf, sizeof(ebuf)));
return -1; return -1;
} }

View File

@ -3723,7 +3723,7 @@ vshGenFileName(vshControl *ctl, virDomainPtr dom, const char *mime)
ext = ".png"; ext = ".png";
/* add mime type here */ /* add mime type here */
time (&cur_time); time(&cur_time);
localtime_r(&cur_time, &time_info); localtime_r(&cur_time, &time_info);
strftime(timestr, sizeof(timestr), "%Y-%m-%d-%H:%M:%S", &time_info); strftime(timestr, sizeof(timestr), "%Y-%m-%d-%H:%M:%S", &time_info);

View File

@ -511,6 +511,7 @@ vshEditWriteToTempFile(vshControl *ctl, const char *doc)
char *ret; char *ret;
const char *tmpdir; const char *tmpdir;
int fd; int fd;
char ebuf[1024];
tmpdir = getenv ("TMPDIR"); tmpdir = getenv ("TMPDIR");
if (!tmpdir) tmpdir = "/tmp"; if (!tmpdir) tmpdir = "/tmp";
@ -521,14 +522,14 @@ vshEditWriteToTempFile(vshControl *ctl, const char *doc)
fd = mkstemps(ret, 4); fd = mkstemps(ret, 4);
if (fd == -1) { if (fd == -1) {
vshError(ctl, _("mkstemps: failed to create temporary file: %s"), vshError(ctl, _("mkstemps: failed to create temporary file: %s"),
strerror(errno)); virStrerror(errno, ebuf, sizeof(ebuf)));
VIR_FREE(ret); VIR_FREE(ret);
return NULL; return NULL;
} }
if (safewrite(fd, doc, strlen(doc)) == -1) { if (safewrite(fd, doc, strlen(doc)) == -1) {
vshError(ctl, _("write: %s: failed to write to temporary file: %s"), vshError(ctl, _("write: %s: failed to write to temporary file: %s"),
ret, strerror(errno)); ret, virStrerror(errno, ebuf, sizeof(ebuf)));
VIR_FORCE_CLOSE(fd); VIR_FORCE_CLOSE(fd);
unlink(ret); unlink(ret);
VIR_FREE(ret); VIR_FREE(ret);
@ -536,7 +537,7 @@ vshEditWriteToTempFile(vshControl *ctl, const char *doc)
} }
if (VIR_CLOSE(fd) < 0) { if (VIR_CLOSE(fd) < 0) {
vshError(ctl, _("close: %s: failed to write or close temporary file: %s"), vshError(ctl, _("close: %s: failed to write or close temporary file: %s"),
ret, strerror(errno)); ret, virStrerror(errno, ebuf, sizeof(ebuf)));
unlink(ret); unlink(ret);
VIR_FREE(ret); VIR_FREE(ret);
return NULL; return NULL;
@ -606,11 +607,12 @@ char *
vshEditReadBackFile(vshControl *ctl, const char *filename) vshEditReadBackFile(vshControl *ctl, const char *filename)
{ {
char *ret; char *ret;
char ebuf[1024];
if (virFileReadAll(filename, VSH_MAX_XML_FILE, &ret) == -1) { if (virFileReadAll(filename, VSH_MAX_XML_FILE, &ret) == -1) {
vshError(ctl, vshError(ctl,
_("%s: failed to read temporary file: %s"), _("%s: failed to read temporary file: %s"),
filename, strerror(errno)); filename, virStrerror(errno, ebuf, sizeof(ebuf)));
return NULL; return NULL;
} }
return ret; return ret;
@ -637,6 +639,7 @@ cmdCd(vshControl *ctl, const vshCmd *cmd)
const char *dir = NULL; const char *dir = NULL;
char *dir_malloced = NULL; char *dir_malloced = NULL;
bool ret = true; bool ret = true;
char ebuf[1024];
if (!ctl->imode) { if (!ctl->imode) {
vshError(ctl, "%s", _("cd: command valid only in interactive mode")); vshError(ctl, "%s", _("cd: command valid only in interactive mode"));
@ -650,7 +653,8 @@ cmdCd(vshControl *ctl, const vshCmd *cmd)
dir = "/"; dir = "/";
if (chdir(dir) == -1) { 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; ret = false;
} }
@ -672,11 +676,12 @@ cmdPwd(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
{ {
char *cwd; char *cwd;
bool ret = true; bool ret = true;
char ebuf[1024];
cwd = getcwd(NULL, 0); cwd = getcwd(NULL, 0);
if (!cwd) { if (!cwd) {
vshError(ctl, _("pwd: cannot get current directory: %s"), vshError(ctl, _("pwd: cannot get current directory: %s"),
strerror(errno)); virStrerror(errno, ebuf, sizeof(ebuf)));
ret = false; ret = false;
} else { } else {
vshPrint(ctl, _("%s\n"), cwd); vshPrint(ctl, _("%s\n"), cwd);
@ -2188,7 +2193,7 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format,
size_t len; size_t len;
const char *lvl = ""; const char *lvl = "";
time_t stTime; time_t stTime;
struct tm *stTm; struct tm stTm;
if (ctl->log_fd == -1) if (ctl->log_fd == -1)
return; 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 * [YYYY.MM.DD HH:MM:SS SIGNATURE PID] LOG_LEVEL message
*/ */
time (&stTime); time(&stTime);
stTm = localtime(&stTime); localtime_r(&stTime, &stTm);
virBufferAsprintf(&buf, "[%d.%02d.%02d %02d:%02d:%02d %s %d] ", virBufferAsprintf(&buf, "[%d.%02d.%02d %02d:%02d:%02d %s %d] ",
(1900 + stTm->tm_year), (1900 + stTm.tm_year),
(1 + stTm->tm_mon), (1 + stTm.tm_mon),
stTm->tm_mday, stTm.tm_mday,
stTm->tm_hour, stTm.tm_hour,
stTm->tm_min, stTm.tm_min,
stTm->tm_sec, stTm.tm_sec,
SIGN_NAME, SIGN_NAME,
(int) getpid()); (int) getpid());
switch (log_level) { switch (log_level) {
@ -2264,10 +2269,13 @@ error:
void void
vshCloseLogFile(vshControl *ctl) vshCloseLogFile(vshControl *ctl)
{ {
char ebuf[1024];
/* log file close */ /* log file close */
if (VIR_CLOSE(ctl->log_fd) < 0) { if (VIR_CLOSE(ctl->log_fd) < 0) {
vshError(ctl, _("%s: failed to write log file: %s"), 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) { if (ctl->logfile) {