The new version allows passing a virBuffer to format the string into.
This will be helpful in solving a memory lean in wrong usage of
virCommandToString and also in tests where we need to add a newline
after the command in certain cases.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/vircommand.c | 50 +++++++++++++++++++++++++---------------
src/util/vircommand.h | 4 ++++
3 files changed, 37 insertions(+), 18 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0ced2a7990..9700e14def 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2037,6 +2037,7 @@ virCommandSetUID;
virCommandSetUmask;
virCommandSetWorkingDirectory;
virCommandToString;
+virCommandToStringBuf;
virCommandToStringFull;
virCommandWait;
virCommandWriteArgLog;
diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index 6e01e4cb62..8e372c3152 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -2053,8 +2053,9 @@ virCommandWriteArgLog(virCommand *cmd, int logfd)
/**
- * virCommandToStringFull:
+ * virCommandToStringBuf:
* @cmd: the command to convert
+ * @buf: buffer to format @cmd into
* @linebreaks: true to break line after each env var or option
* @stripCommandPath: strip the path leading to the binary of @cmd
*
@@ -2062,16 +2063,15 @@ virCommandWriteArgLog(virCommand *cmd, int logfd)
* before Run/RunAsync, to return a string representation of the
* environment and arguments of cmd, suitably quoted for pasting into
* a shell. If virCommandRun cannot succeed (because of an
- * out-of-memory condition while building cmd), NULL will be returned.
- * Caller is responsible for freeing the resulting string.
+ * out-of-memory condition while building cmd), -1 will be returned.
*/
-char *
-virCommandToStringFull(virCommand *cmd,
- bool linebreaks,
- bool stripCommandPath)
+int
+virCommandToStringBuf(virCommand *cmd,
+ virBuffer *buf,
+ bool linebreaks,
+ bool stripCommandPath)
{
size_t i;
- g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
const char *command = cmd->args[0];
g_autofree char *basename = NULL;
bool had_option = false;
@@ -2080,7 +2080,7 @@ virCommandToStringFull(virCommand *cmd,
* now. If virCommandRun is called, it will report the same error. */
if (virCommandHasError(cmd)) {
virCommandRaiseError(cmd);
- return NULL;
+ return -1;
}
for (i = 0; i < cmd->nenv; i++) {
@@ -2091,22 +2091,22 @@ virCommandToStringFull(virCommand *cmd,
if (!eq) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("invalid use of command API"));
- return NULL;
+ return -1;
}
eq++;
- virBufferAdd(&buf, cmd->env[i], eq - cmd->env[i]);
- virBufferEscapeShell(&buf, eq);
- virBufferAddChar(&buf, ' ');
+ virBufferAdd(buf, cmd->env[i], eq - cmd->env[i]);
+ virBufferEscapeShell(buf, eq);
+ virBufferAddChar(buf, ' ');
if (linebreaks)
- virBufferAddLit(&buf, "\\\n");
+ virBufferAddLit(buf, "\\\n");
}
if (stripCommandPath)
command = basename = g_path_get_basename(command);
- virBufferEscapeShell(&buf, command);
+ virBufferEscapeShell(buf, command);
for (i = 1; i < cmd->nargs; i++) {
- virBufferAddChar(&buf, ' ');
+ virBufferAddChar(buf, ' ');
if (linebreaks) {
/* we don't want a linebreak only if
@@ -2131,11 +2131,25 @@ virCommandToStringFull(virCommand *cmd,
}
if (linebreak)
- virBufferAddLit(&buf, "\\\n");
+ virBufferAddLit(buf, "\\\n");
}
- virBufferEscapeShell(&buf, cmd->args[i]);
+ virBufferEscapeShell(buf, cmd->args[i]);
}
+ return 0;
+}
+
+
+char *
+virCommandToStringFull(virCommand *cmd,
+ bool linebreaks,
+ bool stripCommandPath)
+{
+ g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+
+ if (virCommandToStringBuf(cmd, &buf, linebreaks, stripCommandPath))
+ return NULL;
+
return virBufferContentAndReset(&buf);
}
diff --git a/src/util/vircommand.h b/src/util/vircommand.h
index 77cf8c8ec9..fb6c3b5d12 100644
--- a/src/util/vircommand.h
+++ b/src/util/vircommand.h
@@ -173,6 +173,10 @@ char *virCommandToString(virCommand *cmd, bool linebreaks)
G_GNUC_WARN_UNUSED_RE
char *virCommandToStringFull(virCommand *cmd,
bool linebreaks,
bool stripCommandPath);
+int virCommandToStringBuf(virCommand *cmd,
+ virBuffer *buf,
+ bool linebreaks,
+ bool stripCommandPath);
int virCommandGetArgList(virCommand *cmd, char ***args, size_t *nargs);
--
2.31.1