systemctl: split out helper for --type= and allow resetting

Analogous to grandparent commit.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2026-05-14 09:03:12 +02:00
parent ae83ce85b9
commit 04bf62b012
2 changed files with 59 additions and 45 deletions
+2 -1
View File
@@ -1988,7 +1988,8 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<para>The argument is a comma-separated list of unit types such as <option>service</option> and
<option>socket</option>. When units are listed with <command>list-units</command>,
<command>list-dependencies</command>, <command>show</command>, or <command>status</command>,
only units of the specified types will be shown. By default, units of all types are shown.</para>
only units of the specified types will be shown. By default, units of all types are shown.
Use <option>--type=</option> to reset the filter.</para>
<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>
+57 -44
View File
@@ -355,13 +355,6 @@ static int parse_property_argument(const char *value, char ***properties) {
return 0;
}
static void help_types(void) {
if (arg_legend != 0)
puts("Available unit types:");
DUMP_STRING_TABLE(unit_type, UnitType, _UNIT_TYPE_MAX);
}
static int help_states(void) {
if (arg_legend != 0)
puts("Available unit load states:");
@@ -451,6 +444,60 @@ static int parse_states_argument(const char *value, char ***states) {
return 1;
}
static int help_types(void) {
if (arg_legend != 0)
puts("Available unit types:");
return DUMP_STRING_TABLE(unit_type, UnitType, _UNIT_TYPE_MAX);
}
static int parse_types_argument(const char *value, char ***types, char ***states) {
int r;
assert(value);
assert(types);
assert(states);
if (isempty(value)) {
/* reset the setting */
*types = strv_free(*types);
return 1;
}
for (const char *p = value;;) {
_cleanup_free_ char *type = NULL;
r = extract_first_word(&p, &type, ",", /* flags= */ 0);
if (r < 0)
return log_error_errno(r, "Failed to parse -t/--type=: %m");
if (r == 0)
break;
if (streq(type, "help"))
return help_types();
if (unit_type_from_string(type) >= 0) {
if (strv_consume(types, TAKE_PTR(type)) < 0)
return log_oom();
continue;
}
/* It's much nicer to use --state= for load states, but let's support this in
* --types= too for compatibility with old versions */
if (unit_load_state_from_string(type) >= 0) {
if (strv_consume(states, TAKE_PTR(type)) < 0)
return log_oom();
continue;
}
log_error("Unknown unit type or load state '%s'.", type);
return log_info_errno(SYNTHETIC_ERRNO(EINVAL),
"Use -t help to see a list of allowed values.");
}
return 1;
}
static int systemctl_parse_argv(int argc, char *argv[]) {
enum {
ARG_FAIL = 0x100, /* compatibility only */
@@ -597,43 +644,9 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
return version();
case 't':
if (isempty(optarg))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--type= requires arguments.");
for (const char *p = optarg;;) {
_cleanup_free_ char *type = NULL;
r = extract_first_word(&p, &type, ",", 0);
if (r < 0)
return log_error_errno(r, "Failed to parse type: %s", optarg);
if (r == 0)
break;
if (streq(type, "help")) {
help_types();
return 0;
}
if (unit_type_from_string(type) >= 0) {
if (strv_consume(&arg_types, TAKE_PTR(type)) < 0)
return log_oom();
continue;
}
/* It's much nicer to use --state= for load states, but let's support this in
* --types= too for compatibility with old versions */
if (unit_load_state_from_string(type) >= 0) {
if (strv_consume(&arg_states, TAKE_PTR(type)) < 0)
return log_oom();
continue;
}
log_error("Unknown unit type or load state '%s'.", type);
return log_info_errno(SYNTHETIC_ERRNO(EINVAL),
"Use -t help to see a list of allowed values.");
}
r = parse_types_argument(optarg, &arg_types, &arg_states);
if (r <= 0)
return r;
break;
case 'P':