]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
implement lxc_string_split_quoted 1844/head
authorSerge Hallyn <shallyn@cisco.com>
Wed, 4 Oct 2017 05:14:00 +0000 (05:14 +0000)
committerSerge Hallyn <shallyn@cisco.com>
Wed, 4 Oct 2017 18:01:53 +0000 (18:01 +0000)
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.

Signed-off-by: Serge Hallyn <shallyn@cisco.com>
src/lxc/tools/lxc_execute.c
src/lxc/utils.c
src/lxc/utils.h
templates/lxc-oci.in

index f69ab6a5145e4c8235d9859c199674ad85e5d233..234591c476d83b439f6535870ab6850deaaa10c0 100644 (file)
@@ -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;
 
index e6a44a516156d61049a0e5ab528ba7744b91e15e..c9a60979ab23eef58989cdee0312ff7e8dbafc37 100644 (file)
@@ -816,6 +816,74 @@ error_out:
        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;
index e83ed49eba371c2b92ff96534b7c07aef0bbbe16..833ec44167acec339d522fe88708eb44cf35a785 100644 (file)
@@ -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);
 
index f715125f7e6ffe5002cc988e061a4d576921adc8..c2cfb351a1e447abcb1c91a81e7962d77fbe7eda 100755 (executable)
@@ -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