[libvirt] [PATCH 0/2] Introduce safewrite_str

Ján Tomko (2): vsh: use virBufferTrim in vshOutputLogFile Introduce safewrite_str src/conf/virchrdev.c | 2 +- src/libvirt_private.syms | 1 + src/lxc/lxc_process.c | 4 ++-- src/network/leaseshelper.c | 2 +- src/openvz/openvz_conf.c | 15 ++++++--------- src/qemu/qemu_domain.c | 2 +- src/util/vircommand.c | 4 ++-- src/util/virfile.c | 9 ++++++++- src/util/virfile.h | 1 + src/util/virlog.c | 6 +++--- src/util/virpidfile.c | 4 ++-- src/util/virxml.c | 17 ++++++----------- tools/vsh.c | 9 ++------- 13 files changed, 36 insertions(+), 40 deletions(-) -- 2.4.10

Use virBufferTrim to strip the extra newline at the end of the message instead of open-coding it after the buffer's string is formatted. --- tools/vsh.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index 073347a..9dd3ba3 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -2086,6 +2086,7 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format, } virBufferAsprintf(&buf, "%s ", lvl); virBufferVasprintf(&buf, msg_format, ap); + virBufferTrim(&buf, "\n", -1); virBufferAddChar(&buf, '\n'); if (virBufferError(&buf)) @@ -2093,10 +2094,6 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format, str = virBufferContentAndReset(&buf); len = strlen(str); - if (len > 1 && str[len - 2] == '\n') { - str[len - 1] = '\0'; - len--; - } /* write log */ if (safewrite(ctl->log_fd, str, len) < 0) -- 2.4.10

On 02/12/2016 08:59 AM, Ján Tomko wrote:
Use virBufferTrim to strip the extra newline at the end of the message instead of open-coding it after the buffer's string is formatted. --- tools/vsh.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
ACK John

Just like safewrite, but calls strlen first to figure out the length of the string. --- src/conf/virchrdev.c | 2 +- src/libvirt_private.syms | 1 + src/lxc/lxc_process.c | 4 ++-- src/network/leaseshelper.c | 2 +- src/openvz/openvz_conf.c | 15 ++++++--------- src/qemu/qemu_domain.c | 2 +- src/util/vircommand.c | 4 ++-- src/util/virfile.c | 9 ++++++++- src/util/virfile.h | 1 + src/util/virlog.c | 6 +++--- src/util/virpidfile.c | 4 ++-- src/util/virxml.c | 17 ++++++----------- tools/vsh.c | 4 +--- 13 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/conf/virchrdev.c b/src/conf/virchrdev.c index 701b326..1fe1631 100644 --- a/src/conf/virchrdev.c +++ b/src/conf/virchrdev.c @@ -162,7 +162,7 @@ static int virChrdevLockFileCreate(const char *dev) } /* write the pid to the file */ - if (safewrite(lockfd, pidStr, strlen(pidStr)) < 0) { + if (safewrite_str(lockfd, pidStr) < 0) { virReportSystemError(errno, _("Couldn't write to lock file for " "device '%s' in path '%s'"), diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4cfaed5..c17c5e7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1431,6 +1431,7 @@ virEventPollUpdateTimeout; # util/virfile.h saferead; safewrite; +safewrite_str; safezero; virBuildPathInternal; virDirCreate; diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 50bee48..1679411 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -1407,8 +1407,8 @@ int virLXCProcessStart(virConnectPtr conn, /* Log timestamp */ if ((timestamp = virTimeStringNow()) == NULL) goto cleanup; - if (safewrite(logfd, timestamp, strlen(timestamp)) < 0 || - safewrite(logfd, START_POSTFIX, strlen(START_POSTFIX)) < 0) { + if (safewrite_str(logfd, timestamp) < 0 || + safewrite_str(logfd, START_POSTFIX) < 0) { VIR_WARN("Unable to write timestamp to logfile: %s", virStrerror(errno, ebuf, sizeof(ebuf))); } diff --git a/src/network/leaseshelper.c b/src/network/leaseshelper.c index 55ddd58..2414a2f 100644 --- a/src/network/leaseshelper.c +++ b/src/network/leaseshelper.c @@ -84,7 +84,7 @@ customLeaseRewriteFile(int fd, void *opaque) { char **data = opaque; - if (safewrite(fd, *data, strlen(*data)) < 0) + if (safewrite_str(fd, *data) < 0) return -1; return 0; diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c index e32dd6f..edd989e 100644 --- a/src/openvz/openvz_conf.c +++ b/src/openvz/openvz_conf.c @@ -673,16 +673,15 @@ openvzWriteConfigParam(const char * conf_file, const char *param, const char *va break; if (!(STRPREFIX(line, param) && line[strlen(param)] == '=')) { - if (safewrite(temp_fd, line, strlen(line)) != - strlen(line)) + if (safewrite_str(temp_fd, line) < 0) goto error; } } - if (safewrite(temp_fd, param, strlen(param)) < 0 || - safewrite(temp_fd, "=\"", 2) < 0 || - safewrite(temp_fd, value, strlen(value)) < 0 || - safewrite(temp_fd, "\"\n", 2) < 0) + if (safewrite_str(temp_fd, param) < 0 || + safewrite_str(temp_fd, "=\"") < 0 || + safewrite_str(temp_fd, value) < 0 || + safewrite_str(temp_fd, "\"\n") < 0) goto error; if (VIR_FCLOSE(fp) < 0) @@ -801,7 +800,6 @@ openvz_copyfile(char* from_path, char* to_path) size_t line_size = 0; FILE *fp; int copy_fd; - int bytes_read; fp = fopen(from_path, "r"); if (fp == NULL) @@ -816,8 +814,7 @@ openvz_copyfile(char* from_path, char* to_path) if (getline(&line, &line_size, fp) <= 0) break; - bytes_read = strlen(line); - if (safewrite(copy_fd, line, bytes_read) != bytes_read) + if (safewrite_str(copy_fd, line) < 0) goto error; } diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 495c76b..698ddfd 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2481,7 +2481,7 @@ int qemuDomainLogContextWrite(qemuDomainLogContextPtr ctxt, _("Unable to seek to end of domain logfile")); goto cleanup; } - if (safewrite(ctxt->writefd, message, strlen(message)) < 0) { + if (safewrite_str(ctxt->writefd, message) < 0) { virReportSystemError(errno, "%s", _("Unable to write to domain logfile")); goto cleanup; diff --git a/src/util/vircommand.c b/src/util/vircommand.c index fe7bf34..60baca0 100644 --- a/src/util/vircommand.c +++ b/src/util/vircommand.c @@ -1902,13 +1902,13 @@ virCommandWriteArgLog(virCommandPtr cmd, int logfd) return; for (i = 0; i < cmd->nenv; i++) { - if (safewrite(logfd, cmd->env[i], strlen(cmd->env[i])) < 0) + if (safewrite_str(logfd, cmd->env[i]) < 0) ioError = errno; if (safewrite(logfd, " ", 1) < 0) ioError = errno; } for (i = 0; i < cmd->nargs; i++) { - if (safewrite(logfd, cmd->args[i], strlen(cmd->args[i])) < 0) + if (safewrite_str(logfd, cmd->args[i]) < 0) ioError = errno; if (safewrite(logfd, i == cmd->nargs - 1 ? "\n" : " ", 1) < 0) ioError = errno; diff --git a/src/util/virfile.c b/src/util/virfile.c index f45e18f..c4fe10e 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -1066,6 +1066,13 @@ safewrite(int fd, const void *buf, size_t count) return nwritten; } +ssize_t +safewrite_str(int fd, const char *buf) +{ + size_t len = strlen(buf); + return safewrite(fd, buf, len); +} + #ifdef HAVE_POSIX_FALLOCATE static int safezero_posix_fallocate(int fd, off_t offset, off_t len) @@ -1418,7 +1425,7 @@ virFileWriteStr(const char *path, const char *str, mode_t mode) if (fd == -1) return -1; - if (safewrite(fd, str, strlen(str)) < 0) { + if (safewrite_str(fd, str) < 0) { VIR_FORCE_CLOSE(fd); return -1; } diff --git a/src/util/virfile.h b/src/util/virfile.h index 312f226..12df539 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -41,6 +41,7 @@ typedef enum { ssize_t saferead(int fd, void *buf, size_t count) ATTRIBUTE_RETURN_CHECK; ssize_t safewrite(int fd, const void *buf, size_t count) ATTRIBUTE_RETURN_CHECK; +ssize_t safewrite_str(int fd, const char *buf) ATTRIBUTE_RETURN_CHECK; int safezero(int fd, off_t offset, off_t len) ATTRIBUTE_RETURN_CHECK; diff --git a/src/util/virlog.c b/src/util/virlog.c index b8398d1..3015d1a 100644 --- a/src/util/virlog.c +++ b/src/util/virlog.c @@ -681,9 +681,9 @@ virLogStackTraceToFd(int fd) size = backtrace(array, ARRAY_CARDINALITY(array)); if (size) { backtrace_symbols_fd(array + STRIP_DEPTH, size - STRIP_DEPTH, fd); - ignore_value(safewrite(fd, "\n", 1)); + ignore_value(safewrite_str(fd, "\n")); } else if (!doneWarning) { - ignore_value(safewrite(fd, msg, strlen(msg))); + ignore_value(safewrite_str(fd, msg)); doneWarning = true; } #undef STRIP_DEPTH @@ -711,7 +711,7 @@ virLogOutputToFd(virLogSourcePtr source ATTRIBUTE_UNUSED, if (virAsprintfQuiet(&msg, "%s: %s", timestamp, str) < 0) return; - ignore_value(safewrite(fd, msg, strlen(msg))); + ignore_value(safewrite_str(fd, msg)); VIR_FREE(msg); if (flags & VIR_LOG_STACK_TRACE) diff --git a/src/util/virpidfile.c b/src/util/virpidfile.c index 58ab29f..d000fc2 100644 --- a/src/util/virpidfile.c +++ b/src/util/virpidfile.c @@ -77,7 +77,7 @@ int virPidFileWritePath(const char *pidfile, snprintf(pidstr, sizeof(pidstr), "%lld", (long long) pid); - if (safewrite(fd, pidstr, strlen(pidstr)) < 0) { + if (safewrite_str(fd, pidstr) < 0) { rc = -errno; VIR_FORCE_CLOSE(fd); goto cleanup; @@ -446,7 +446,7 @@ int virPidFileAcquirePath(const char *path, snprintf(pidstr, sizeof(pidstr), "%lld", (long long) pid); - if (safewrite(fd, pidstr, strlen(pidstr)) < 0) { + if (safewrite_str(fd, pidstr) < 0) { virReportSystemError(errno, _("Failed to write to pid file '%s'"), path); diff --git a/src/util/virxml.c b/src/util/virxml.c index 489bad8..aeed9ce 100644 --- a/src/util/virxml.c +++ b/src/util/virxml.c @@ -796,7 +796,6 @@ static int virXMLEmitWarning(int fd, const char *name, const char *cmd) { - size_t len; const char *prologue = "<!--\n" "WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE\n" @@ -812,25 +811,21 @@ static int virXMLEmitWarning(int fd, return -1; } - len = strlen(prologue); - if (safewrite(fd, prologue, len) != len) + if (safewrite_str(fd, prologue) < 0) return -1; - len = strlen(cmd); - if (safewrite(fd, cmd, len) != len) + if (safewrite_str(fd, cmd) < 0) return -1; if (name) { - if (safewrite(fd, " ", 1) != 1) + if (safewrite_str(fd, " ") < 0) return -1; - len = strlen(name); - if (safewrite(fd, name, len) != len) + if (safewrite_str(fd, name) < 0) return -1; } - len = strlen(epilogue); - if (safewrite(fd, epilogue, len) != len) + if (safewrite_str(fd, epilogue) < 0) return -1; return 0; @@ -853,7 +848,7 @@ virXMLRewriteFile(int fd, void *opaque) return -1; } - if (safewrite(fd, data->xml, strlen(data->xml)) < 0) + if (safewrite_str(fd, data->xml) < 0) return -1; return 0; diff --git a/tools/vsh.c b/tools/vsh.c index 9dd3ba3..62b034c 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -2040,7 +2040,6 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format, { virBuffer buf = VIR_BUFFER_INITIALIZER; char *str = NULL; - size_t len; const char *lvl = ""; time_t stTime; struct tm stTm; @@ -2093,10 +2092,9 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format, goto error; str = virBufferContentAndReset(&buf); - len = strlen(str); /* write log */ - if (safewrite(ctl->log_fd, str, len) < 0) + if (safewrite_str(ctl->log_fd, str) < 0) goto error; VIR_FREE(str); -- 2.4.10

On 02/12/2016 08:59 AM, Ján Tomko wrote:
Just like safewrite, but calls strlen first to figure out the length of the string. --- src/conf/virchrdev.c | 2 +- src/libvirt_private.syms | 1 + src/lxc/lxc_process.c | 4 ++-- src/network/leaseshelper.c | 2 +- src/openvz/openvz_conf.c | 15 ++++++--------- src/qemu/qemu_domain.c | 2 +- src/util/vircommand.c | 4 ++-- src/util/virfile.c | 9 ++++++++- src/util/virfile.h | 1 + src/util/virlog.c | 6 +++--- src/util/virpidfile.c | 4 ++-- src/util/virxml.c | 17 ++++++----------- tools/vsh.c | 4 +--- 13 files changed, 35 insertions(+), 36 deletions(-)
Conflicted about this one - the difference between the two appears to be 'safewrite' will write a some length of a string (e.g. a counted length) while safewrite_str writes the entire string. To make things more interesting some safewrite calls use sizeof instead of strlen, but in reality are just writing everything in the buffer. So, perhaps 'safewrite_all' or 'safewrite_full' better describes the new functionality? I also started looking at some of the other safewrite calls to see if any more fell into the bucket of write everything and few more jumped out at me. Some used sizeof instead of strlen and some uses of strlen were better hidden, such as: * secretSaveDef vectors through replaceFile * update_include_file The other thing that I noted is error checking is not consistent. While checking < 0 does ensure that the write() call didn't fail, what if the number of bytes written != the number of bytes we tried to write? So maybe this is a good opportunity to make all this consistent for all callers. BTW: saferead is in a similar situation...
diff --git a/src/conf/virchrdev.c b/src/conf/virchrdev.c index 701b326..1fe1631 100644 --- a/src/conf/virchrdev.c +++ b/src/conf/virchrdev.c @@ -162,7 +162,7 @@ static int virChrdevLockFileCreate(const char *dev) }
/* write the pid to the file */ - if (safewrite(lockfd, pidStr, strlen(pidStr)) < 0) { + if (safewrite_str(lockfd, pidStr) < 0) { virReportSystemError(errno, _("Couldn't write to lock file for " "device '%s' in path '%s'"), diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4cfaed5..c17c5e7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1431,6 +1431,7 @@ virEventPollUpdateTimeout; # util/virfile.h saferead; safewrite; +safewrite_str; safezero; virBuildPathInternal; virDirCreate; diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 50bee48..1679411 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -1407,8 +1407,8 @@ int virLXCProcessStart(virConnectPtr conn, /* Log timestamp */ if ((timestamp = virTimeStringNow()) == NULL) goto cleanup; - if (safewrite(logfd, timestamp, strlen(timestamp)) < 0 || - safewrite(logfd, START_POSTFIX, strlen(START_POSTFIX)) < 0) { + if (safewrite_str(logfd, timestamp) < 0 || + safewrite_str(logfd, START_POSTFIX) < 0) { VIR_WARN("Unable to write timestamp to logfile: %s", virStrerror(errno, ebuf, sizeof(ebuf))); } diff --git a/src/network/leaseshelper.c b/src/network/leaseshelper.c index 55ddd58..2414a2f 100644 --- a/src/network/leaseshelper.c +++ b/src/network/leaseshelper.c @@ -84,7 +84,7 @@ customLeaseRewriteFile(int fd, void *opaque) { char **data = opaque;
- if (safewrite(fd, *data, strlen(*data)) < 0) + if (safewrite_str(fd, *data) < 0) return -1;
return 0; diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c index e32dd6f..edd989e 100644 --- a/src/openvz/openvz_conf.c +++ b/src/openvz/openvz_conf.c @@ -673,16 +673,15 @@ openvzWriteConfigParam(const char * conf_file, const char *param, const char *va break;
if (!(STRPREFIX(line, param) && line[strlen(param)] == '=')) { - if (safewrite(temp_fd, line, strlen(line)) != - strlen(line)) + if (safewrite_str(temp_fd, line) < 0) goto error; } }
- if (safewrite(temp_fd, param, strlen(param)) < 0 || - safewrite(temp_fd, "=\"", 2) < 0 || - safewrite(temp_fd, value, strlen(value)) < 0 || - safewrite(temp_fd, "\"\n", 2) < 0) + if (safewrite_str(temp_fd, param) < 0 || + safewrite_str(temp_fd, "=\"") < 0 || + safewrite_str(temp_fd, value) < 0 || + safewrite_str(temp_fd, "\"\n") < 0) goto error;
if (VIR_FCLOSE(fp) < 0) @@ -801,7 +800,6 @@ openvz_copyfile(char* from_path, char* to_path) size_t line_size = 0; FILE *fp; int copy_fd; - int bytes_read;
fp = fopen(from_path, "r"); if (fp == NULL) @@ -816,8 +814,7 @@ openvz_copyfile(char* from_path, char* to_path) if (getline(&line, &line_size, fp) <= 0) break;
- bytes_read = strlen(line); - if (safewrite(copy_fd, line, bytes_read) != bytes_read) + if (safewrite_str(copy_fd, line) < 0) goto error; }
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 495c76b..698ddfd 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2481,7 +2481,7 @@ int qemuDomainLogContextWrite(qemuDomainLogContextPtr ctxt, _("Unable to seek to end of domain logfile")); goto cleanup; } - if (safewrite(ctxt->writefd, message, strlen(message)) < 0) { + if (safewrite_str(ctxt->writefd, message) < 0) { virReportSystemError(errno, "%s", _("Unable to write to domain logfile")); goto cleanup; diff --git a/src/util/vircommand.c b/src/util/vircommand.c index fe7bf34..60baca0 100644 --- a/src/util/vircommand.c +++ b/src/util/vircommand.c @@ -1902,13 +1902,13 @@ virCommandWriteArgLog(virCommandPtr cmd, int logfd) return;
for (i = 0; i < cmd->nenv; i++) { - if (safewrite(logfd, cmd->env[i], strlen(cmd->env[i])) < 0) + if (safewrite_str(logfd, cmd->env[i]) < 0) ioError = errno; if (safewrite(logfd, " ", 1) < 0) ioError = errno; } for (i = 0; i < cmd->nargs; i++) { - if (safewrite(logfd, cmd->args[i], strlen(cmd->args[i])) < 0) + if (safewrite_str(logfd, cmd->args[i]) < 0) ioError = errno; if (safewrite(logfd, i == cmd->nargs - 1 ? "\n" : " ", 1) < 0) ioError = errno; diff --git a/src/util/virfile.c b/src/util/virfile.c index f45e18f..c4fe10e 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -1066,6 +1066,13 @@ safewrite(int fd, const void *buf, size_t count) return nwritten; }
Could use an intro comment about usage... As well as a returns statement... Since neither generates an error message it's up to the caller to handle that... Not all callers do that today.
+ssize_t +safewrite_str(int fd, const char *buf) +{ + size_t len = strlen(buf); + return safewrite(fd, buf, len);
So this only returns failure if write() fails; however: size_t written = safewrite(fd, buf, len); if (written != len) /* different variable types... */ return -1; return written; John
+} + #ifdef HAVE_POSIX_FALLOCATE static int safezero_posix_fallocate(int fd, off_t offset, off_t len) @@ -1418,7 +1425,7 @@ virFileWriteStr(const char *path, const char *str, mode_t mode) if (fd == -1) return -1;
- if (safewrite(fd, str, strlen(str)) < 0) { + if (safewrite_str(fd, str) < 0) { VIR_FORCE_CLOSE(fd); return -1; } diff --git a/src/util/virfile.h b/src/util/virfile.h index 312f226..12df539 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -41,6 +41,7 @@ typedef enum { ssize_t saferead(int fd, void *buf, size_t count) ATTRIBUTE_RETURN_CHECK; ssize_t safewrite(int fd, const void *buf, size_t count) ATTRIBUTE_RETURN_CHECK; +ssize_t safewrite_str(int fd, const char *buf) ATTRIBUTE_RETURN_CHECK; int safezero(int fd, off_t offset, off_t len) ATTRIBUTE_RETURN_CHECK;
diff --git a/src/util/virlog.c b/src/util/virlog.c index b8398d1..3015d1a 100644 --- a/src/util/virlog.c +++ b/src/util/virlog.c @@ -681,9 +681,9 @@ virLogStackTraceToFd(int fd) size = backtrace(array, ARRAY_CARDINALITY(array)); if (size) { backtrace_symbols_fd(array + STRIP_DEPTH, size - STRIP_DEPTH, fd); - ignore_value(safewrite(fd, "\n", 1)); + ignore_value(safewrite_str(fd, "\n")); } else if (!doneWarning) { - ignore_value(safewrite(fd, msg, strlen(msg))); + ignore_value(safewrite_str(fd, msg)); doneWarning = true; } #undef STRIP_DEPTH @@ -711,7 +711,7 @@ virLogOutputToFd(virLogSourcePtr source ATTRIBUTE_UNUSED, if (virAsprintfQuiet(&msg, "%s: %s", timestamp, str) < 0) return;
- ignore_value(safewrite(fd, msg, strlen(msg))); + ignore_value(safewrite_str(fd, msg)); VIR_FREE(msg);
if (flags & VIR_LOG_STACK_TRACE) diff --git a/src/util/virpidfile.c b/src/util/virpidfile.c index 58ab29f..d000fc2 100644 --- a/src/util/virpidfile.c +++ b/src/util/virpidfile.c @@ -77,7 +77,7 @@ int virPidFileWritePath(const char *pidfile,
snprintf(pidstr, sizeof(pidstr), "%lld", (long long) pid);
- if (safewrite(fd, pidstr, strlen(pidstr)) < 0) { + if (safewrite_str(fd, pidstr) < 0) { rc = -errno; VIR_FORCE_CLOSE(fd); goto cleanup; @@ -446,7 +446,7 @@ int virPidFileAcquirePath(const char *path,
snprintf(pidstr, sizeof(pidstr), "%lld", (long long) pid);
- if (safewrite(fd, pidstr, strlen(pidstr)) < 0) { + if (safewrite_str(fd, pidstr) < 0) { virReportSystemError(errno, _("Failed to write to pid file '%s'"), path); diff --git a/src/util/virxml.c b/src/util/virxml.c index 489bad8..aeed9ce 100644 --- a/src/util/virxml.c +++ b/src/util/virxml.c @@ -796,7 +796,6 @@ static int virXMLEmitWarning(int fd, const char *name, const char *cmd) { - size_t len; const char *prologue = "<!--\n" "WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE\n" @@ -812,25 +811,21 @@ static int virXMLEmitWarning(int fd, return -1; }
- len = strlen(prologue); - if (safewrite(fd, prologue, len) != len) + if (safewrite_str(fd, prologue) < 0) return -1;
- len = strlen(cmd); - if (safewrite(fd, cmd, len) != len) + if (safewrite_str(fd, cmd) < 0) return -1;
if (name) { - if (safewrite(fd, " ", 1) != 1) + if (safewrite_str(fd, " ") < 0) return -1;
- len = strlen(name); - if (safewrite(fd, name, len) != len) + if (safewrite_str(fd, name) < 0) return -1; }
- len = strlen(epilogue); - if (safewrite(fd, epilogue, len) != len) + if (safewrite_str(fd, epilogue) < 0) return -1;
return 0; @@ -853,7 +848,7 @@ virXMLRewriteFile(int fd, void *opaque) return -1; }
- if (safewrite(fd, data->xml, strlen(data->xml)) < 0) + if (safewrite_str(fd, data->xml) < 0) return -1;
return 0; diff --git a/tools/vsh.c b/tools/vsh.c index 9dd3ba3..62b034c 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -2040,7 +2040,6 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format, { virBuffer buf = VIR_BUFFER_INITIALIZER; char *str = NULL; - size_t len; const char *lvl = ""; time_t stTime; struct tm stTm; @@ -2093,10 +2092,9 @@ vshOutputLogFile(vshControl *ctl, int log_level, const char *msg_format, goto error;
str = virBufferContentAndReset(&buf); - len = strlen(str);
/* write log */ - if (safewrite(ctl->log_fd, str, len) < 0) + if (safewrite_str(ctl->log_fd, str) < 0) goto error;
VIR_FREE(str);

On Thu, Feb 18, 2016 at 07:40:12AM -0500, John Ferlan wrote:
On 02/12/2016 08:59 AM, Ján Tomko wrote:
Just like safewrite, but calls strlen first to figure out the length of the string. --- src/conf/virchrdev.c | 2 +- src/libvirt_private.syms | 1 + src/lxc/lxc_process.c | 4 ++-- src/network/leaseshelper.c | 2 +- src/openvz/openvz_conf.c | 15 ++++++--------- src/qemu/qemu_domain.c | 2 +- src/util/vircommand.c | 4 ++-- src/util/virfile.c | 9 ++++++++- src/util/virfile.h | 1 + src/util/virlog.c | 6 +++--- src/util/virpidfile.c | 4 ++-- src/util/virxml.c | 17 ++++++----------- tools/vsh.c | 4 +--- 13 files changed, 35 insertions(+), 36 deletions(-)
Conflicted about this one - the difference between the two appears to be 'safewrite' will write a some length of a string (e.g. a counted length) while safewrite_str writes the entire string.
Safewrite writes data from a buffer, it does not have to be a string (i.e. it can write more than a string).
To make things more interesting some safewrite calls use sizeof instead of strlen, but in reality are just writing everything in the buffer.
So, perhaps 'safewrite_all' or 'safewrite_full' better describes the new functionality?
Unlike virFileReadAll where we get EOF after 'all' ends, there is no such marker when reading from memory. We have no way of telling what 'all' is unless we opreate on a string.
I also started looking at some of the other safewrite calls to see if any more fell into the bucket of write everything and few more jumped out at me. Some used sizeof instead of strlen and some uses of strlen were better hidden, such as:
* secretSaveDef vectors through replaceFile
That whole function reimplements virFileRewrite.
* update_include_file
And this one could just reuse the return value of virAsprintf.
The other thing that I noted is error checking is not consistent. While checking < 0 does ensure that the write() call didn't fail, what if the number of bytes written != the number of bytes we tried to write?
Our safewrite function calls write in a loop, so this would only happen if write returns success and returned zero bytes on the last call, which should not ever happen (TM) for regular files. Jan
So maybe this is a good opportunity to make all this consistent for all callers.
BTW: saferead is in a similar situation...

On Thu, Feb 18, 2016 at 07:40:12AM -0500, John Ferlan wrote:
On 02/12/2016 08:59 AM, Ján Tomko wrote:
Just like safewrite, but calls strlen first to figure out the length of the string. --- src/conf/virchrdev.c | 2 +- src/libvirt_private.syms | 1 + src/lxc/lxc_process.c | 4 ++-- src/network/leaseshelper.c | 2 +- src/openvz/openvz_conf.c | 15 ++++++--------- src/qemu/qemu_domain.c | 2 +- src/util/vircommand.c | 4 ++-- src/util/virfile.c | 9 ++++++++- src/util/virfile.h | 1 + src/util/virlog.c | 6 +++--- src/util/virpidfile.c | 4 ++-- src/util/virxml.c | 17 ++++++----------- tools/vsh.c | 4 +--- 13 files changed, 35 insertions(+), 36 deletions(-)
Conflicted about this one - the difference between the two appears to be 'safewrite' will write a some length of a string (e.g. a counted length) while safewrite_str writes the entire string. To make things more interesting some safewrite calls use sizeof instead of strlen, but in reality are just writing everything in the buffer.
So, perhaps 'safewrite_all' or 'safewrite_full' better describes the new functionality?
I don't think we need any new function actually. Just add this to existing safewrite() method: if (len == -1) len = strlen(data) and then update the callers which pass a NULL terminated string to just pass -1. This matches our behaviour with virBuffer APIs which acccept a length of -1. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Tue, Feb 23, 2016 at 01:19:38PM +0000, Daniel P. Berrange wrote:
On Thu, Feb 18, 2016 at 07:40:12AM -0500, John Ferlan wrote:
On 02/12/2016 08:59 AM, Ján Tomko wrote:
Just like safewrite, but calls strlen first to figure out the length of the string. --- src/conf/virchrdev.c | 2 +- src/libvirt_private.syms | 1 + src/lxc/lxc_process.c | 4 ++-- src/network/leaseshelper.c | 2 +- src/openvz/openvz_conf.c | 15 ++++++--------- src/qemu/qemu_domain.c | 2 +- src/util/vircommand.c | 4 ++-- src/util/virfile.c | 9 ++++++++- src/util/virfile.h | 1 + src/util/virlog.c | 6 +++--- src/util/virpidfile.c | 4 ++-- src/util/virxml.c | 17 ++++++----------- tools/vsh.c | 4 +--- 13 files changed, 35 insertions(+), 36 deletions(-)
Conflicted about this one - the difference between the two appears to be 'safewrite' will write a some length of a string (e.g. a counted length) while safewrite_str writes the entire string. To make things more interesting some safewrite calls use sizeof instead of strlen, but in reality are just writing everything in the buffer.
So, perhaps 'safewrite_all' or 'safewrite_full' better describes the new functionality?
I don't think we need any new function actually.
Just add this to existing safewrite() method:
if (len == -1) len = strlen(data)
and then update the callers which pass a NULL terminated string to just pass -1. This matches our behaviour with virBuffer APIs which acccept a length of -1.
In fact for the case where the caller passes a literal string we could add #define safewritelit(fd_, literal_string_) \ safewrite(fd_, "" literal_string_ "", sizeof(literal_string_) - 1) which moves the performance hit of strlen() to be compile time instead of runtime. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
participants (3)
-
Daniel P. Berrange
-
John Ferlan
-
Ján Tomko