diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2013-04-10 22:40:58 -0400 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2013-04-11 19:11:52 -0400 |
commit | 20b3f379cfd44e61dd1838a107f1d5363fab5b5d (patch) | |
tree | 026941d6a711a91d38e4422c99215c8ecbf6e8b1 /src/systemctl/systemctl.c | |
parent | 296f3c53cb4a87e297c019475f900fb3cca2d781 (diff) |
systemctl: allow multiple arguments to --type
This mirrors --property, and is generally useful.
New functionality is used in bash completion.
In case of zsh completion, new functionality is less useful
because of caching. Nevertheless, zsh completion for restart
is made to behave more-or-less the same as bash completion.
At least sockets can be restarted.
Diffstat (limited to 'src/systemctl/systemctl.c')
-rw-r--r-- | src/systemctl/systemctl.c | 104 |
1 files changed, 64 insertions, 40 deletions
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index af7ecd7af1..0e6087c62a 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -68,9 +68,9 @@ #include "socket-util.h" #include "fileio.h" -static const char *arg_type = NULL; -static const char *arg_load_state = NULL; -static char **arg_property = NULL; +static char **arg_types = NULL; +static char **arg_load_states = NULL; +static char **arg_properties = NULL; static bool arg_all = false; static const char *arg_job_mode = "replace"; static UnitFileScope arg_scope = UNIT_FILE_SYSTEM; @@ -295,9 +295,9 @@ static bool output_show_unit(const struct unit_info *u) { if (arg_failed) return streq(u->active_state, "failed"); - return (!arg_type || ((dot = strrchr(u->id, '.')) && - streq(dot+1, arg_type))) && - (!arg_load_state || streq(u->load_state, arg_load_state)) && + return (!arg_types || ((dot = strrchr(u->id, '.')) && + strv_find(arg_types, dot+1))) && + (!arg_load_states || strv_find(arg_load_states, u->load_state)) && (arg_all || !(streq(u->active_state, "inactive") || u->following[0]) || u->job_id > 0); } @@ -524,7 +524,7 @@ static int compare_unit_file_list(const void *a, const void *b) { static bool output_show_unit_file(const UnitFileList *u) { const char *dot; - return !arg_type || ((dot = strrchr(u->path, '.')) && streq(dot+1, arg_type)); + return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1)); } static void output_unit_file_list(const UnitFileList *units, unsigned c) { @@ -2946,7 +2946,7 @@ static int print_property(const char *name, DBusMessageIter *iter) { /* This is a low-level property printer, see * print_status_info() for the nicer output */ - if (arg_property && !strv_find(arg_property, name)) + if (arg_properties && !strv_find(arg_properties, name)) return 0; switch (dbus_message_iter_get_arg_type(iter)) { @@ -4504,45 +4504,67 @@ static int systemctl_parse_argv(int argc, char *argv[]) { puts(SYSTEMD_FEATURES); return 0; - case 't': - if (streq(optarg, "help")) { - help_types(); - return 0; - } + case 't': { + char *word, *state; + size_t size; - if (unit_type_from_string(optarg) >= 0) { - arg_type = optarg; - break; - } - if (unit_load_state_from_string(optarg) >= 0) { - arg_load_state = optarg; - break; + FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) { + char _cleanup_free_ *type; + + type = strndup(word, size); + if (!type) + return -ENOMEM; + + if (streq(type, "help")) { + help_types(); + return 0; + } + + if (unit_type_from_string(type) >= 0) { + if (strv_push(&arg_types, type)) + return log_oom(); + type = NULL; + continue; + } + + if (unit_load_state_from_string(optarg) >= 0) { + if (strv_push(&arg_load_states, type)) + return log_oom(); + type = NULL; + continue; + } + + log_error("Unkown unit type or load state '%s'.", type); + log_info("Use -t help to see a list of allowed values."); + return -EINVAL; } - log_error("Unkown unit type or load state '%s'.", - optarg); - log_info("Use -t help to see a list of allowed values."); - return -EINVAL; + + break; + } + case 'p': { - char *word, *state; - size_t size; /* Make sure that if the empty property list was specified, we won't show any properties. */ - const char *source = isempty(optarg) ? " " : optarg; + if (isempty(optarg) && !arg_properties) { + arg_properties = strv_new(NULL, NULL); + if (!arg_properties) + return log_oom(); + } else { + char *word, *state; + size_t size; - FOREACH_WORD_SEPARATOR(word, size, source, ",", state) { - char _cleanup_free_ *prop; - char **tmp; + FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) { + char *prop; - prop = strndup(word, size); - if (!prop) - return -ENOMEM; + prop = strndup(word, size); + if (!prop) + return log_oom(); - tmp = strv_append(arg_property, prop); - if (!tmp) - return -ENOMEM; - - strv_free(arg_property); - arg_property = tmp; + if (strv_push(&arg_properties, prop)) { + free(prop); + return log_oom(); + } + } } /* If the user asked for a particular @@ -5725,7 +5747,9 @@ finish: dbus_shutdown(); - strv_free(arg_property); + strv_free(arg_types); + strv_free(arg_load_states); + strv_free(arg_properties); pager_close(); ask_password_agent_close(); |