If lxc_container_new() fails we check for ENOMEN and goto out if ENOMEM is not set we will simply continue. The same goes for the call to regcomp() but instead of checking for ENOMEM we need to check for REG_ESPACE.
Tweaking: Since lxc-ls might have to gather a lot of containers and I don't know if compilers will always optimize this let's move all variable declarations outside of the loop. They should still be fairly self explanatory. Signed-off-by: Christian Brauner <christian.brau...@mailbox.org> --- src/lxc/lxc_ls.c | 57 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/src/lxc/lxc_ls.c b/src/lxc/lxc_ls.c index a4ab9b6..7d46426 100644 --- a/src/lxc/lxc_ls.c +++ b/src/lxc/lxc_ls.c @@ -341,25 +341,37 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args, goto out; } + char lock_path[MAXPATHLEN]; + char *curr_path, *name, *newpath, *tmp; + const char *state_tmp; + int check = 0; + size_t i; + bool running; struct ls *l = NULL; struct lxc_container *c = NULL; - size_t i; + struct wrapargs wargs = (struct wrapargs){.args = NULL}; for (i = 0; i < (size_t)num; i++) { - char *name = containers[i]; + name = containers[i]; /* Filter container names by regex the user gave us. */ if (args->ls_regex) { regex_t preg; - if (regcomp(&preg, args->ls_regex, REG_NOSUB | REG_EXTENDED) != 0) + check = regcomp(&preg, args->ls_regex, REG_NOSUB | REG_EXTENDED); + if (check == REG_ESPACE) /* we're out of memory */ + goto out; + else if (check != 0) continue; - int rc = regexec(&preg, name, 0, NULL, 0); + check = regexec(&preg, name, 0, NULL, 0); regfree(&preg); - if (rc != 0) + if (check != 0) continue; } + errno = 0; c = lxc_container_new(name, path); - if (!c) + if ((errno == ENOMEM) && !c) + goto out; + else if (!c) continue; if (!c->is_defined(c)) @@ -367,7 +379,7 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args, /* This does not allocate memory so no worries about freeing it * when we goto next or out. */ - const char *state_tmp = c->state(c); + state_tmp = c->state(c); if (!state_tmp) state_tmp = "UNKNOWN"; @@ -380,11 +392,11 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args, if (args->ls_stopped && strcmp(state_tmp, "STOPPED")) goto put_and_next; - bool running = c->is_running(c); + running = c->is_running(c); - char *grp_tmp = ls_get_groups(c, running); - if (!ls_has_all_grps(grp_tmp, args->groups)) { - free(grp_tmp); + tmp = ls_get_groups(c, running); + if (!ls_has_all_grps(tmp, args->groups)) { + free(tmp); goto put_and_next; } @@ -396,7 +408,7 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args, /* How deeply nested are we? */ l->nestlvl = lvl; - l->groups = grp_tmp; + l->groups = tmp; l->running = running; @@ -422,7 +434,7 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args, if (!l->state) goto put_and_next; - char *tmp = ls_get_config_item(c, "lxc.start.auto", running); + tmp = ls_get_config_item(c, "lxc.start.auto", running); if (tmp) l->autostart = atoi(tmp); free(tmp); @@ -450,12 +462,10 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args, /* Get nested containers: Only do this after we have gathered * all other information we need. */ if (args->ls_nesting && running) { - struct wrapargs wargs = (struct wrapargs){.args = NULL}; - /* Open a socket so that the child can communicate with * us. */ - int ret = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, wargs.pipefd); - if (ret == -1) + check = socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, wargs.pipefd); + if (check == -1) goto put_and_next; /* Set the next nesting level. */ @@ -472,12 +482,12 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args, /* fork(): Attach to the namespace of the child and run * ls_get() in it which is called in ls_get_wrapper(). */ - int status = c->attach(c, ls_get_wrapper, &wargs, &aopt, &out); + check = c->attach(c, ls_get_wrapper, &wargs, &aopt, &out); /* close the socket */ close(wargs.pipefd[1]); /* Retrieve all information we want from the child. */ - if (status == 0) + if (check == 0) if (ls_deserialize(wargs.pipefd[0], m, size) == -1) goto put_and_next; @@ -495,7 +505,7 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args, * need a path-extractor function. We face the same * problem with the ovl_mkdir() function in * lxcoverlay.{c,h}. */ - char *curr_path = ls_get_config_item(c, "lxc.rootfs", running); + curr_path = ls_get_config_item(c, "lxc.rootfs", running); if (!curr_path) goto put_and_next; @@ -504,7 +514,7 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args, * nested containers. What we do is simply create a * growing path which will lead us into the rootfs of * the next container where it stores its containers. */ - char *newpath = lxc_append_paths(basepath, curr_path); + newpath = lxc_append_paths(basepath, curr_path); free(curr_path); if (!newpath) goto put_and_next; @@ -512,9 +522,8 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args, /* We want to remove all locks we created under * /run/lxc/lock so we create a string pointing us to * the lock path for the current container. */ - char lock_path[MAXPATHLEN]; - int ret = snprintf(lock_path, MAXPATHLEN, "%s/lxc/lock/%s/%s", RUNTIME_PATH, path, name); - if (ret < 0 || ret >= MAXPATHLEN) + check = snprintf(lock_path, MAXPATHLEN, "%s/lxc/lock/%s/%s", RUNTIME_PATH, path, name); + if (check < 0 || ret >= MAXPATHLEN) goto put_and_next; /* Remove the lock. */ -- 2.7.0 _______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel