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

So far we'd reject --state=, but it seems nicer to make it reset the
setting as we generally do. The output variable is modified in place…
Option parsing isn't atomic anyway, so I think it's fine to to that.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2026-05-14 09:03:11 +02:00
parent 94e05aca0d
commit 979ecbb14e
2 changed files with 40 additions and 26 deletions
+4 -3
View File
@@ -2000,9 +2000,10 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<listitem>
<para>The argument is a comma-separated list of unit LOAD, SUB, or ACTIVE states. When listing
units with <command>list-units</command>, <command>list-dependencies</command>, <command>show</command>
or <command>status</command>, show only those in the specified states. Use <option>--state=failed</option>
or <option>--failed</option> to show only failed units.</para>
units with <command>list-units</command>, <command>list-dependencies</command>,
<command>show</command> or <command>status</command>, show only those in the specified states. Use
<option>--state=failed</option> or <option>--failed</option> to show only failed units. Use
<option>--state=</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>
+36 -23
View File
@@ -334,7 +334,7 @@ static void help_types(void) {
DUMP_STRING_TABLE(unit_type, UnitType, _UNIT_TYPE_MAX);
}
static void help_states(void) {
static int help_states(void) {
if (arg_legend != 0)
puts("Available unit load states:");
DUMP_STRING_TABLE(unit_load_state, UnitLoadState, _UNIT_LOAD_STATE_MAX);
@@ -389,7 +389,38 @@ static void help_states(void) {
if (arg_legend != 0)
puts("\nAvailable timer unit substates:");
DUMP_STRING_TABLE(timer_state, TimerState, _TIMER_STATE_MAX);
return DUMP_STRING_TABLE(timer_state, TimerState, _TIMER_STATE_MAX);
}
static int parse_states_argument(const char *value, char ***states) {
int r;
assert(value);
assert(states);
if (isempty(value)) {
/* reset the setting */
*states = strv_free(*states);
return 1;
}
for (const char *p = value;;) {
_cleanup_free_ char *s = NULL;
r = extract_first_word(&p, &s, ",", /* flags= */ 0);
if (r < 0)
return log_error_errno(r, "Failed to parse --state=: %m");
if (r == 0)
break;
if (streq(s, "help"))
return help_states();
if (strv_consume(states, TAKE_PTR(s)) < 0)
return log_oom();
}
return 1;
}
static int systemctl_parse_argv(int argc, char *argv[]) {
@@ -869,27 +900,9 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break;
case ARG_STATE:
if (isempty(optarg))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--state= requires arguments.");
for (const char *p = optarg;;) {
_cleanup_free_ char *s = NULL;
r = extract_first_word(&p, &s, ",", 0);
if (r < 0)
return log_error_errno(r, "Failed to parse state: %s", optarg);
if (r == 0)
break;
if (streq(s, "help")) {
help_states();
return 0;
}
if (strv_consume(&arg_states, TAKE_PTR(s)) < 0)
return log_oom();
}
r = parse_states_argument(optarg, &arg_states);
if (r <= 0)
return r;
break;
case 'r':