core: convert to VERB_COMMAND and add --introspect-cli
--introspect-cli follows the same deferred pattern as --help: parse_argv() only records the action, and it is executed in the same place where ACTION_HELP and ACTION_VERSION are handled. The help is looked up by explicit name: in the multicall configuration the systemd and systemd-executor commands share one binary, so the "first COMMAND" default would depend on link order. The "This program takes no positional arguments." line is dropped from the help output — the default "[OPTION…]" synopsis already says so. (And also, this is not quite true. It does take positional args when called as init.)
This commit is contained in:
@@ -37,6 +37,7 @@ int proc_cmdline_filter_pid1_args(char **argv, char ***ret) {
|
||||
{ "no-pager", no_argument, },
|
||||
{ "help", no_argument, },
|
||||
{ "version", no_argument, },
|
||||
{ "introspect-cli", no_argument, },
|
||||
{ "dump-configuration-items", no_argument, },
|
||||
{ "dump-bus-properties", no_argument, },
|
||||
{ "bus-introspect", required_argument },
|
||||
|
||||
+22
-26
@@ -51,13 +51,11 @@
|
||||
#include "fd-util.h"
|
||||
#include "fdset.h"
|
||||
#include "fileio.h"
|
||||
#include "format-table.h"
|
||||
#include "format-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "glyph-util.h"
|
||||
#include "hash-funcs.h"
|
||||
#include "hashmap.h"
|
||||
#include "help-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "hostname-setup.h"
|
||||
#include "id128-util.h"
|
||||
@@ -119,6 +117,7 @@
|
||||
#include "unit-name.h"
|
||||
#include "user-util.h"
|
||||
#include "utf8.h"
|
||||
#include "verbs.h"
|
||||
#include "version.h"
|
||||
#include "virt.h"
|
||||
#include "watchdog.h"
|
||||
@@ -131,6 +130,7 @@ static enum {
|
||||
ACTION_RUN,
|
||||
ACTION_HELP,
|
||||
ACTION_VERSION,
|
||||
ACTION_INTROSPECT_CLI,
|
||||
ACTION_TEST,
|
||||
ACTION_DUMP_CONFIGURATION_ITEMS,
|
||||
ACTION_DUMP_BUS_PROPERTIES,
|
||||
@@ -1039,6 +1039,14 @@ static int redirect_telinit(char *argv[], char **args) {
|
||||
strnull(a), strnull(b), strnull(c));
|
||||
}
|
||||
|
||||
COMMAND(
|
||||
"systemd\0",
|
||||
"Start and monitor system and user services.",
|
||||
.man_pages = "systemd.1\0",
|
||||
.option_namespace = "systemd",
|
||||
.pager_flags = &arg_pager_flags,
|
||||
);
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
bool user_arg_seen = false;
|
||||
int r;
|
||||
@@ -1068,6 +1076,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_action = ACTION_VERSION;
|
||||
break;
|
||||
|
||||
OPTION_COMMON_INTROSPECT_CLI:
|
||||
arg_action = ACTION_INTROSPECT_CLI;
|
||||
break;
|
||||
|
||||
OPTION_LONG("test", NULL, "Determine initial transaction, dump it and exit"):
|
||||
arg_action = ACTION_TEST;
|
||||
break;
|
||||
@@ -1268,6 +1280,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
"Switch -%c is only supported when running as PID 1.", opts.opt->short_code);
|
||||
/* In PID1, do nothing and continue with option parsing. */
|
||||
break;
|
||||
|
||||
OPTION_ERROR:
|
||||
if (getpid_cached() != 1)
|
||||
return -EINVAL;
|
||||
@@ -1290,28 +1303,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = option_parser_get_help_table_ns("systemd", &options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_cmdline("[OPTIONS...]");
|
||||
help_abstract("Starts and monitors system and user services.");
|
||||
|
||||
printf("\nThis program takes no positional arguments.\n");
|
||||
|
||||
help_section("Options");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_man_page_reference("systemd", "1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int prepare_reexecute(
|
||||
Manager *m,
|
||||
FILE **ret_f,
|
||||
@@ -3745,18 +3736,23 @@ static int run_systemd(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
if (IN_SET(arg_action, ACTION_TEST, ACTION_HELP, ACTION_DUMP_CONFIGURATION_ITEMS, ACTION_DUMP_BUS_PROPERTIES, ACTION_BUS_INTROSPECT))
|
||||
if (IN_SET(arg_action, ACTION_TEST, ACTION_DUMP_CONFIGURATION_ITEMS, ACTION_DUMP_BUS_PROPERTIES, ACTION_BUS_INTROSPECT))
|
||||
pager_open(arg_pager_flags);
|
||||
|
||||
if (arg_action != ACTION_RUN)
|
||||
skip_setup = true;
|
||||
|
||||
if (arg_action == ACTION_HELP) {
|
||||
retval = help() < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
r = command_print_help_name("systemd");
|
||||
retval = r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
goto finish;
|
||||
} else if (arg_action == ACTION_VERSION) {
|
||||
retval = version();
|
||||
goto finish;
|
||||
} else if (arg_action == ACTION_INTROSPECT_CLI) {
|
||||
r = introspect_cli(SD_JSON_FORMAT_OFF);
|
||||
retval = r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
goto finish;
|
||||
} else if (arg_action == ACTION_DUMP_CONFIGURATION_ITEMS) {
|
||||
unit_dump_config_items(stdout);
|
||||
retval = EXIT_SUCCESS;
|
||||
|
||||
@@ -271,9 +271,10 @@ TEST(proc_cmdline_filter_pid1_args) {
|
||||
"--log-color\0--log-level\0drop3\0" /* optional argument ("--log-level" is handled as another option) */
|
||||
"--log-color\0accept5\0" /* optional argument (separated with space) */
|
||||
"--log-color=drop4\0accept6\0" /* optional argument (concatenated with '=') */
|
||||
"--introspect-cli\0accept7\0" /* no argument */
|
||||
"--log-color\0--\0" /* "--" is _not_ handled as argument, and remaining strings are accepted */
|
||||
"remaining\0-x\0--foo\0",
|
||||
STRV_MAKE("accept1", "accept2", "accept3", "accept4", "accept5", "accept6", "remaining", "-x", "--foo"));
|
||||
STRV_MAKE("accept1", "accept2", "accept3", "accept4", "accept5", "accept6", "accept7", "remaining", "-x", "--foo"));
|
||||
|
||||
/* test for "--" */
|
||||
test_proc_cmdline_filter_pid1_args_one("systemd\0"
|
||||
|
||||
@@ -40,6 +40,7 @@ INTROSPECTABLE=(
|
||||
shutdown
|
||||
storagectl
|
||||
systemctl
|
||||
systemd
|
||||
systemd-ac-power
|
||||
systemd-analyze
|
||||
systemd-ask-password
|
||||
@@ -205,6 +206,12 @@ fi
|
||||
systemd-id128 --introspect-cli | jq -e \
|
||||
'.commands[0].verbs | map(.names[0]) | contains(["new", "machine-id", "show", "help"])'
|
||||
|
||||
# systemd is optionally a multicall binary that also provides systemd-executor
|
||||
if [[ "$(readlink "$(command -v systemd-executor)" 2>/dev/null)" == systemd ]]; then
|
||||
systemd --introspect-cli | jq -e \
|
||||
'[.commands[].names[0]] | sort == ["systemd", "systemd-executor"]'
|
||||
fi
|
||||
|
||||
if command -v systemd-mount >/dev/null; then
|
||||
systemd-mount --introspect-cli | jq -e \
|
||||
'[.commands[].names[0]] | sort == ["systemd-mount", "systemd-umount"]'
|
||||
|
||||
Reference in New Issue
Block a user