Restore old behaviour [filter] behaviour

In the Python implementation users could pass a regex without a parameter flag
as additional argument on the command line. The C implementation gained the
flag -r/--regex for this. To not irritate users we restore the old behaviour
and additionally rename -r/--regex to --filter to allow eplicitly passing the
regex.

Signed-off-by: Christian Brauner <christian.brauner@mailbox.org>
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
This commit is contained in:
Christian Brauner 2016-01-28 12:21:29 +01:00 committed by Stéphane Graber
parent 07385df53e
commit 4763f6cade
2 changed files with 21 additions and 18 deletions

View File

@ -123,7 +123,7 @@ struct lxc_arguments {
/* lxc-ls */ /* lxc-ls */
char *ls_fancy_format; char *ls_fancy_format;
char *ls_groups; char *ls_groups;
char *ls_regex; char *ls_filter;
unsigned int ls_nesting; /* maximum allowed nesting level */ unsigned int ls_nesting; /* maximum allowed nesting level */
bool ls_active; bool ls_active;
bool ls_fancy; bool ls_fancy;

View File

@ -49,6 +49,7 @@ lxc_log_define(lxc_ls, lxc);
#define LS_ACTIVE 3 #define LS_ACTIVE 3
#define LS_RUNNING 4 #define LS_RUNNING 4
#define LS_NESTING 5 #define LS_NESTING 5
#define LS_FILTER 6
/* Store container info. */ /* Store container info. */
struct ls { struct ls {
@ -93,8 +94,8 @@ static void ls_free_arr(char **arr, size_t size);
* container) cannot be retrieved. * container) cannot be retrieved.
*/ */
static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args, static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args,
struct lengths *lht, const char *basepath, const char *parent, const char *basepath, const char *parent, unsigned int lvl,
unsigned int lvl, char **lockpath, size_t len_lockpath); char **lockpath, size_t len_lockpath);
static char *ls_get_cgroup_item(struct lxc_container *c, const char *item); static char *ls_get_cgroup_item(struct lxc_container *c, const char *item);
static char *ls_get_config_item(struct lxc_container *c, const char *item, static char *ls_get_config_item(struct lxc_container *c, const char *item,
bool running); bool running);
@ -102,7 +103,6 @@ static char *ls_get_groups(struct lxc_container *c, bool running);
static char *ls_get_ips(struct lxc_container *c, const char *inet); static char *ls_get_ips(struct lxc_container *c, const char *inet);
struct wrapargs { struct wrapargs {
const struct lxc_arguments *args; const struct lxc_arguments *args;
struct lengths *lht;
int pipefd[2]; int pipefd[2];
size_t *size; size_t *size;
const char *parent; const char *parent;
@ -162,7 +162,7 @@ static const struct option my_longopts[] = {
{"stopped", no_argument, 0, LS_STOPPED}, {"stopped", no_argument, 0, LS_STOPPED},
{"nesting", optional_argument, 0, LS_NESTING}, {"nesting", optional_argument, 0, LS_NESTING},
{"groups", required_argument, 0, 'g'}, {"groups", required_argument, 0, 'g'},
{"regex", required_argument, 0, 'r'}, {"filter", required_argument, 0, LS_FILTER},
LXC_COMMON_OPTIONS LXC_COMMON_OPTIONS
}; };
@ -233,7 +233,7 @@ int main(int argc, char *argv[])
/* &(char *){NULL} is no magic. It's just a compound literal which /* &(char *){NULL} is no magic. It's just a compound literal which
* avoids having a pointless variable in main() that serves no purpose * avoids having a pointless variable in main() that serves no purpose
* here. */ * here. */
int status = ls_get(&ls_arr, &ls_size, &my_args, &max_len, "", NULL, 0, &(char *){NULL}, 0); int status = ls_get(&ls_arr, &ls_size, &my_args, "", NULL, 0, &(char *){NULL}, 0);
if (!ls_arr && status == 0) if (!ls_arr && status == 0)
/* We did not fail. There was just nothing to do. */ /* We did not fail. There was just nothing to do. */
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
@ -307,8 +307,8 @@ static void ls_free_arr(char **arr, size_t size)
} }
static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args, static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args,
struct lengths *lht, const char *basepath, const char *parent, const char *basepath, const char *parent, unsigned int lvl,
unsigned int lvl, char **lockpath, size_t len_lockpath) char **lockpath, size_t len_lockpath)
{ {
/* As ls_get() is non-tail recursive we face the inherent danger of /* As ls_get() is non-tail recursive we face the inherent danger of
* blowing up the stack at some level of nesting. To have at least some * blowing up the stack at some level of nesting. To have at least some
@ -355,9 +355,10 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args,
char *name = containers[i]; char *name = containers[i];
/* Filter container names by regex the user gave us. */ /* Filter container names by regex the user gave us. */
if (args->ls_regex) { if (args->ls_filter || args->argc == 1) {
regex_t preg; regex_t preg;
check = regcomp(&preg, args->ls_regex, REG_NOSUB | REG_EXTENDED); tmp = args->ls_filter ? args->ls_filter : args->argv[0];
check = regcomp(&preg, tmp, REG_NOSUB | REG_EXTENDED);
if (check == REG_ESPACE) /* we're out of memory */ if (check == REG_ESPACE) /* we're out of memory */
goto out; goto out;
else if (check != 0) else if (check != 0)
@ -476,7 +477,6 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args,
/* Send in the parent for the next nesting level. */ /* Send in the parent for the next nesting level. */
wargs.parent = l->name; wargs.parent = l->name;
wargs.args = args; wargs.args = args;
wargs.lht = lht;
pid_t out; pid_t out;
@ -528,11 +528,11 @@ static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args,
if (ls_remove_lock(path, name, lockpath, &len_lockpath, true) == -1) if (ls_remove_lock(path, name, lockpath, &len_lockpath, true) == -1)
goto put_and_next; goto put_and_next;
ls_get(m, size, args, lht, newpath, l->name, lvl + 1, lockpath, len_lockpath); ls_get(m, size, args, newpath, l->name, lvl + 1, lockpath, len_lockpath);
free(newpath); free(newpath);
/* Remove the lock. No need to check for failure here. */ /* Remove the lock. No need to check for failure here. */
ls_remove_lock(path, name, lockpath, &len_lockpath, false) ls_remove_lock(path, name, lockpath, &len_lockpath, false);
} }
put_and_next: put_and_next:
@ -688,13 +688,16 @@ static bool ls_has_all_grps(const char *has, const char *must)
if (tmp_must_len > tmp_has_len) if (tmp_must_len > tmp_has_len)
tmp_must_len = tmp_has_len = 0; tmp_must_len = tmp_has_len = 0;
bool broke_out = false; bool broke_out = false, ran_once = false;
char **s, **t; char **s, **t;
/* Check if container has all relevant groups. */ /* Check if container has all relevant groups. */
for (s = tmp_must; (tmp_must_len > 0) && (tmp_has_len > 0) && s && *s; s++) { for (s = tmp_must; (tmp_must_len > 0) && (tmp_has_len > 0) && s && *s; s++) {
if (broke_out) if (broke_out)
broke_out = false; broke_out = false;
else if (!broke_out && ran_once)
break;
for (t = tmp_has; t && *t; t++) { for (t = tmp_has; t && *t; t++) {
ran_once = true;
if (strcmp(*s, *t) == 0) { if (strcmp(*s, *t) == 0) {
broke_out = true; broke_out = true;
break; break;
@ -922,8 +925,8 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg)
case 'g': case 'g':
args->groups = arg; args->groups = arg;
break; break;
case 'r': case LS_FILTER:
args->ls_regex = arg; args->ls_filter = arg;
break; break;
case 'F': case 'F':
args->ls_fancy_format = arg; args->ls_fancy_format = arg;
@ -946,7 +949,7 @@ static int ls_get_wrapper(void *wrap)
/* &(char *){NULL} is no magic. It's just a compound literal which /* &(char *){NULL} is no magic. It's just a compound literal which
* avoids having a pointless variable in main() that serves no purpose * avoids having a pointless variable in main() that serves no purpose
* here. */ * here. */
ls_get(&m, &len, wargs->args, wargs->lht, "", wargs->parent, wargs->nestlvl, &(char *){NULL}, 0); ls_get(&m, &len, wargs->args, "", wargs->parent, wargs->nestlvl, &(char *){NULL}, 0);
if (!m) if (!m)
goto out; goto out;
@ -985,7 +988,7 @@ static int ls_remove_lock(const char *path, const char *name,
} }
int check = snprintf(*lockpath, *len_lockpath, "%s/lxc/lock/%s/%s", RUNTIME_PATH, path, name); int check = snprintf(*lockpath, *len_lockpath, "%s/lxc/lock/%s/%s", RUNTIME_PATH, path, name);
if (check < 0 || check >= *len_lockpath) if (check < 0 || (size_t)check >= *len_lockpath)
return -1; return -1;
lxc_rmdir_onedev(*lockpath, NULL); lxc_rmdir_onedev(*lockpath, NULL);