From fd51a89b60d06f1f207196e5fe6e8e8f7bea3beb Mon Sep 17 00:00:00 2001 From: Serge Hallyn Date: Thu, 5 Nov 2015 22:18:52 +0000 Subject: [PATCH] support arguments in lxc.init_cmd MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Otherwise something like lxc.init_cmd = /sbin/init debug verbose fails trying to execute a file called "/sbin/init debug verbose" Signed-off-by: Serge Hallyn Acked-by: Stéphane Graber --- src/lxc/lxccontainer.c | 83 +++++++++++++++++++++++++++++++++++------- 1 file changed, 69 insertions(+), 14 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index eccc154fc..87a941cd9 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -618,10 +618,64 @@ static bool am_single_threaded(void) return count == 1; } -/* - * I can't decide if it'd be more convenient for callers if we accept '...', - * or a null-terminated array (i.e. execl vs execv) - */ +static void push_arg(char ***argp, char *arg, int *nargs) +{ + char **argv; + char *copy; + + do { + copy = strdup(arg); + } while (!copy); + do { + argv = realloc(*argp, (*nargs + 2) * sizeof(char *)); + } while (!argv); + *argp = argv; + argv[*nargs] = copy; + (*nargs)++; + argv[*nargs] = NULL; +} + +static char **split_init_cmd(const char *incmd) +{ + size_t len; + int nargs = 0; + char *copy, *p, *saveptr; + char **argv; + + if (!incmd) + return NULL; + + len = strlen(incmd) + 1; + copy = alloca(len); + strncpy(copy, incmd, len); + copy[len-1] = '\0'; + + do { + argv = malloc(sizeof(char *)); + } while (!argv); + argv[0] = NULL; + for (p = strtok_r(copy, " ", &saveptr); p != NULL; + p = strtok_r(NULL, " ", &saveptr)) + push_arg(&argv, p, &nargs); + + if (nargs == 0) { + free(argv); + return NULL; + } + return argv; +} + +static void free_init_cmd(char **argv) +{ + int i = 0; + + if (!argv) + return; + while (argv[i]) + free(argv[i++]); + free(argv); +} + static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const argv[]) { int ret; @@ -632,7 +686,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a "/sbin/init", NULL, }; - char *init_cmd[2]; + char **init_cmd = NULL; /* container exists */ if (!c) @@ -673,15 +727,14 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a return ret == 0 ? true : false; } - if (!argv) { - if (conf->init_cmd) { - init_cmd[0] = conf->init_cmd; - init_cmd[1] = NULL; - argv = init_cmd; - } - else - argv = default_args; - } + /* if no argv was passed in, use lxc.init_cmd if provided in + * configuration */ + if (!argv) + argv = init_cmd = split_init_cmd(conf->init_cmd); + + /* ... and otherwise use default_args */ + if (!argv) + argv = default_args; /* * say, I'm not sure - what locks do we want here? Any? @@ -790,6 +843,8 @@ out: c->pidfile = NULL; } + free_init_cmd(init_cmd); + if (daemonize) exit (ret == 0 ? true : false); else -- 2.47.2