chiark / gitweb /
systemctl: allow multiple arguments to --type
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 11 Apr 2013 02:40:58 +0000 (22:40 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 11 Apr 2013 23:11:52 +0000 (19:11 -0400)
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.

man/systemctl.xml
shell-completion/bash/systemctl
shell-completion/systemd-zsh-completion.zsh
src/systemctl/systemctl.c

index 5656564f54bf6837bb9f37123efcae460369db27..97bc47ce241b261f93a2410f48491daec61f7ba7 100644 (file)
@@ -92,21 +92,22 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>.
         <term><option>--type=</option></term>
 
         <listitem>
-          <para>The argument should be a unit type name such as
-          <option>service</option> and <option>socket</option>, or a
-          unit load state such as <option>loaded</option> and
-          <option>masked</option>.
-          </para>
-
-          <para>If the argument is a unit type, when listing units,
-          limit display to certain unit types. If not specified units
+          <para>The argument should be a comma separated list of unit
+          types such as <option>service</option> and
+          <option>socket</option>, or unit load states such as
+          <option>loaded</option> and <option>masked</option>
+          (types and states can be mixed).</para>
+
+          <para>If one of the arguments is a unit type, when listing
+          units, limit display to certain unit types. Otherwise units
           of all types will be shown.</para>
 
-          <para>If the argument is a unit load state, when listing
-          units, limit display to certain unit types. If not specified
-          units of in all load states will be shown.</para>
+          <para>If one of the arguments is a unit load state, when
+          listing units, limit display to certain unit
+          types. Otherwise units of in all load states will be
+          shown.</para>
 
-          <para>As a special case, if the argument is
+          <para>As a special case, if one of the arguments is
           <option>help</option>, a list of allowed values will be
           printed and the program will exit.</para>
         </listitem>
index aba76f65433ea5b17d92a863360a745c85eec732..f24a1454245b8afb2032f1e0fa582ed5796417f8 100644 (file)
@@ -45,7 +45,7 @@ __get_all_units      () { __systemctl $1 list-units --all \
         | { while read -r a b; do echo " $a"; done; }; }
 __get_active_units   () { __systemctl $1 list-units       \
         | { while read -r a b; do echo " $a"; done; }; }
-__get_inactive_units () { __systemctl $1 list-units --all \
+__get_startable_units () { __systemctl $1 list-units --all -t service,timer,socket,mount,automount,path,snapshot,swap \
         | { while read -r a b c d; do [[ $c == "inactive" || $c == "failed " ]] && echo " $a"; done; }; }
 __get_failed_units   () { __systemctl $1 list-units       \
         | { while read -r a b c d; do [[ $c == "failed"   ]] && echo " $a"; done; }; }
@@ -156,10 +156,7 @@ _systemctl () {
 
         elif __contains_word "$verb" ${VERBS[STARTABLE_UNITS]}; then
                 comps=$( __filter_units_by_property $mode CanStart yes \
-                      $( __get_inactive_units $mode \
-                        | while read -r line; do \
-                                [[ "$line" =~ \.(device|snapshot)$ ]] || echo " $line"; \
-                        done ))
+                      $( __get_startable_units $mode))
 
         elif __contains_word "$verb" ${VERBS[RESTARTABLE_UNITS]}; then
                 comps=$( __filter_units_by_property $mode CanStart yes \
index a54e9d727ade070a2207c5ddf2f9674adef5435b..8b60859c23654e57e52b1912cfb3a5d756468762 100644 (file)
@@ -536,7 +536,7 @@ for fun in restart reload-or-restart ; do
     _systemctl_all_units
     compadd "$@" - $( _filter_units_by_property CanStart yes \
       ${_sys_all_units[*]} | while read line; do \
-      [[ "$line" =~ \.(device|snapshot|socket|timer)$ ]] || echo " $line"; \
+      [[ "$line" =~ \.device$ ]] || echo " $line"; \
       done )
   }
 done
index af7ecd7af15d8e89f7e8e375c7b2ec58afa47a0c..0e6087c62a278c4a0b72cd4d88a60756fa48723e 100644 (file)
@@ -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();