From: Zbigniew Jędrzejewski-Szmek Date: Wed, 13 May 2026 15:00:00 +0000 (+0200) Subject: systemctl: split out helper for --state= and allow resetting X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=979ecbb14ee03150a277e021cdec902f7c40f481;p=thirdparty%2Fsystemd.git 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. --- diff --git a/man/systemctl.xml b/man/systemctl.xml index b8ba0f945e9..355956c8adb 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -2000,9 +2000,10 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err The argument is a comma-separated list of unit LOAD, SUB, or ACTIVE states. When listing - units with list-units, list-dependencies, show - or status, show only those in the specified states. Use - or to show only failed units. + units with list-units, list-dependencies, + show or status, show only those in the specified states. Use + or to show only failed units. Use + to reset the filter. As a special case, if one of the arguments is , a list of allowed values will be printed and the program will exit. diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 775188b5191..47f34e1ad34 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -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':