[lxc-devel] [lxc/master] implement lxc_string_split_quoted
hallyn on Github
lxc-bot at linuxcontainers.org
Wed Oct 4 06:00:13 UTC 2017
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 766 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20171004/0fd8a9b4/attachment.bin>
-------------- next part --------------
From c47e94c9bc11b192fe592234da1c4a0849746d25 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <shallyn at cisco.com>
Date: Wed, 4 Oct 2017 05:14:00 +0000
Subject: [PATCH] implement lxc_string_split_quoted
lxc_string_split_quoted() splits a string on spaces, but keeps
groups in single or double qoutes together. In other words,
generally what we'd want for argv behavior.
Switch lxc-execute to use this for lxc.execute.cmd.
Switch lxc-oci template to put the lxc.execute.cmd inside single
quotes, because parse_line() will eat those. If we don't do that,
then if we have lxc.execute.cmd = /bin/echo "hello, world", then the
last double quote will disappear.
---
src/lxc/tools/lxc_execute.c | 5 +---
src/lxc/utils.c | 68 +++++++++++++++++++++++++++++++++++++++++++++
src/lxc/utils.h | 1 +
templates/lxc-oci.in | 2 +-
4 files changed, 71 insertions(+), 5 deletions(-)
diff --git a/src/lxc/tools/lxc_execute.c b/src/lxc/tools/lxc_execute.c
index f69ab6a51..234591c47 100644
--- a/src/lxc/tools/lxc_execute.c
+++ b/src/lxc/tools/lxc_execute.c
@@ -99,10 +99,7 @@ static bool set_argv(struct lxc_conf *conf, struct lxc_arguments *args)
if (!conf->execute_cmd)
return false;
- /* TODO -
- we should honor '"' etc; This seems worth a new helper in utils.c.
- */
- components = lxc_string_split(conf->execute_cmd, ' ');
+ components = lxc_string_split_quoted(conf->execute_cmd);
if (!components)
return false;
diff --git a/src/lxc/utils.c b/src/lxc/utils.c
index e6a44a516..c9a60979a 100644
--- a/src/lxc/utils.c
+++ b/src/lxc/utils.c
@@ -816,6 +816,74 @@ char **lxc_string_split(const char *string, char _sep)
return NULL;
}
+static bool complete_word(char ***result, char *start, char *end, size_t *cap, size_t *cnt)
+{
+ int r;
+
+ r = lxc_grow_array((void ***)result, cap, 2 + *cnt, 16);
+ if (r < 0)
+ return false;
+ (*result)[*cnt] = strndup(start, end - start);
+ if (!(*result)[*cnt])
+ return false;
+ (*cnt)++;
+
+ return true;
+}
+
+/*
+ * Given a a string 'one two "three four"', split into three words,
+ * one, two, and "three four"
+ */
+char **lxc_string_split_quoted(char *string)
+{
+ char *nextword = string, *p, state;
+ char **result = NULL;
+ size_t result_capacity = 0;
+ size_t result_count = 0;
+
+ if (!string || !*string)
+ return calloc(1, sizeof(char *));
+
+ // TODO I'm *not* handling escaped quote
+ state = ' ';
+ for (p = string; *p; p++) {
+ switch(state) {
+ case ' ':
+ if (isspace(*p))
+ continue;
+ else if (*p == '"' || *p == '\'') {
+ nextword = p;
+ state = *p;
+ continue;
+ }
+ nextword = p;
+ state = 'a';
+ continue;
+ case 'a':
+ if (isspace(*p)) {
+ complete_word(&result, nextword, p, &result_capacity, &result_count);
+ state = ' ';
+ continue;
+ }
+ continue;
+ case '"':
+ case '\'':
+ if (*p == state) {
+ complete_word(&result, nextword+1, p, &result_capacity, &result_count);
+ state = ' ';
+ continue;
+ }
+ continue;
+ }
+ }
+
+ if (state == 'a')
+ complete_word(&result, nextword, p, &result_capacity, &result_count);
+
+ return realloc(result, (result_count + 1) * sizeof(char *));
+}
+
char **lxc_string_split_and_trim(const char *string, char _sep)
{
char *token, *str, *saveptr = NULL;
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index e83ed49eb..833ec4416 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -292,6 +292,7 @@ extern bool lxc_string_in_list(const char *needle, const char *haystack,
char sep);
extern char **lxc_string_split(const char *string, char sep);
extern char **lxc_string_split_and_trim(const char *string, char sep);
+extern char **lxc_string_split_quoted(char *string);
/* Append string to NULL-terminated string array. */
extern int lxc_append_string(char ***list, char *entry);
diff --git a/templates/lxc-oci.in b/templates/lxc-oci.in
index f715125f7..c2cfb351a 100755
--- a/templates/lxc-oci.in
+++ b/templates/lxc-oci.in
@@ -197,7 +197,7 @@ entrypoint=$(getep ${DOWNLOAD_TEMP} latest)
rm -rf "${LXC_ROOTFS}.tmp"
LXC_CONF_FILE="${LXC_PATH}/config"
-echo "lxc.execute.cmd = ${entrypoint}" >> "${LXC_CONF_FILE}"
+echo "lxc.execute.cmd = '${entrypoint}'" >> "${LXC_CONF_FILE}"
echo "lxc.mount.auto = proc:mixed sys:mixed cgroup:mixed" >> "${LXC_CONF_FILE}"
echo "lxc.uts.name = ${LXC_NAME}" >> ${LXC_PATH}/config
More information about the lxc-devel
mailing list