mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-05 04:25:19 +00:00
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:
parent
8386b304b0
commit
44342a0efe
2
cfg.mk
2
cfg.mk
@ -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/.*)$$
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user