From: Zbigniew Jędrzejewski-Szmek Date: Thu, 14 May 2026 17:44:22 +0000 (+0200) Subject: basic: fold getopt-defs.h into proc-cmdline.c X-Git-Tag: v261-rc1~157^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4bfdb3c62f78a34736f6debeade4a849317f5dc7;p=thirdparty%2Fsystemd.git basic: fold getopt-defs.h into proc-cmdline.c It'd be nice if we could not repeat the information about the option list a second time. But I don't see a nice way to do this, since (by design) with the macro approach, the macros must be intertwined with the parse_argv() code. But that code in turn refers to a bunch of variables, so lifting out the function is not immediately possible. So I think it's best to keep the existing approach where we provide a list of options, without additional context, and skip them using a custom routine. --- diff --git a/TODO.md b/TODO.md index fe13b0b24df..d9d9e7dd9fc 100644 --- a/TODO.md +++ b/TODO.md @@ -3021,6 +3021,9 @@ SPDX-License-Identifier: LGPL-2.1-or-later - whenever we receive fds via SCM_RIGHTS make sure none got dropped due to the reception limit the kernel silently enforces. +- after option+verb introspection is added, add a test to verify that the + list in proc-cmdline.c matches the actual option list in systemd and shutdown. + - write a document explaining how to write correct udev rules. Mention things such as: 1. do not do lists of vid/pid matches, use hwdb for that diff --git a/src/basic/getopt-defs.h b/src/basic/getopt-defs.h deleted file mode 100644 index 9abef6f1566..00000000000 --- a/src/basic/getopt-defs.h +++ /dev/null @@ -1,77 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -#pragma once - -#include - -#define SYSTEMD_GETOPT_SHORT_OPTIONS "hDbsz:" - -#define COMMON_GETOPT_ARGS \ - ARG_LOG_LEVEL = 0x100, \ - ARG_LOG_TARGET, \ - ARG_LOG_COLOR, \ - ARG_LOG_LOCATION, \ - ARG_LOG_TIME - -#define SYSTEMD_GETOPT_ARGS \ - ARG_UNIT, \ - ARG_SYSTEM, \ - ARG_USER, \ - ARG_TEST, \ - ARG_NO_PAGER, \ - ARG_VERSION, \ - ARG_DUMP_CONFIGURATION_ITEMS, \ - ARG_DUMP_BUS_PROPERTIES, \ - ARG_BUS_INTROSPECT, \ - ARG_DUMP_CORE, \ - ARG_CRASH_CHVT, \ - ARG_CRASH_SHELL, \ - ARG_CRASH_REBOOT, \ - ARG_CRASH_ACTION, \ - ARG_CONFIRM_SPAWN, \ - ARG_SHOW_STATUS, \ - ARG_DESERIALIZE, \ - ARG_SWITCHED_ROOT, \ - ARG_DEFAULT_STD_OUTPUT, \ - ARG_DEFAULT_STD_ERROR, \ - ARG_MACHINE_ID, \ - ARG_SERVICE_WATCHDOGS - -#define SHUTDOWN_GETOPT_ARGS \ - ARG_EXIT_CODE, \ - ARG_TIMEOUT - -#define COMMON_GETOPT_OPTIONS \ - { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, \ - { "log-target", required_argument, NULL, ARG_LOG_TARGET }, \ - { "log-color", optional_argument, NULL, ARG_LOG_COLOR }, \ - { "log-location", optional_argument, NULL, ARG_LOG_LOCATION }, \ - { "log-time", optional_argument, NULL, ARG_LOG_TIME } - -#define SYSTEMD_GETOPT_OPTIONS \ - { "unit", required_argument, NULL, ARG_UNIT }, \ - { "system", no_argument, NULL, ARG_SYSTEM }, \ - { "user", no_argument, NULL, ARG_USER }, \ - { "test", no_argument, NULL, ARG_TEST }, \ - { "no-pager", no_argument, NULL, ARG_NO_PAGER }, \ - { "help", no_argument, NULL, 'h' }, \ - { "version", no_argument, NULL, ARG_VERSION }, \ - { "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS }, \ - { "dump-bus-properties", no_argument, NULL, ARG_DUMP_BUS_PROPERTIES }, \ - { "bus-introspect", required_argument, NULL, ARG_BUS_INTROSPECT }, \ - { "dump-core", optional_argument, NULL, ARG_DUMP_CORE }, \ - { "crash-chvt", required_argument, NULL, ARG_CRASH_CHVT }, \ - { "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL }, \ - { "crash-reboot", optional_argument, NULL, ARG_CRASH_REBOOT }, \ - { "crash-action", required_argument, NULL, ARG_CRASH_ACTION }, \ - { "confirm-spawn", optional_argument, NULL, ARG_CONFIRM_SPAWN }, \ - { "show-status", optional_argument, NULL, ARG_SHOW_STATUS }, \ - { "deserialize", required_argument, NULL, ARG_DESERIALIZE }, \ - { "switched-root", no_argument, NULL, ARG_SWITCHED_ROOT }, \ - { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, }, \ - { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, }, \ - { "machine-id", required_argument, NULL, ARG_MACHINE_ID }, \ - { "service-watchdogs", required_argument, NULL, ARG_SERVICE_WATCHDOGS } - -#define SHUTDOWN_GETOPT_OPTIONS \ - { "exit-code", required_argument, NULL, ARG_EXIT_CODE }, \ - { "timeout", required_argument, NULL, ARG_TIMEOUT } diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c index eb61b0bc554..4de3480ff02 100644 --- a/src/basic/proc-cmdline.c +++ b/src/basic/proc-cmdline.c @@ -5,7 +5,6 @@ #include "alloc-util.h" #include "extract-word.h" #include "fileio.h" -#include "getopt-defs.h" #include "initrd-util.h" #include "log.h" #include "parse-util.h" @@ -15,18 +14,50 @@ #include "strv.h" #include "virt.h" +typedef enum ArgType { + no_argument, + required_argument, + optional_argument, +} ArgType; + int proc_cmdline_filter_pid1_args(char **argv, char ***ret) { - enum { - COMMON_GETOPT_ARGS, - SYSTEMD_GETOPT_ARGS, - SHUTDOWN_GETOPT_ARGS, - }; - static const struct option options[] = { - COMMON_GETOPT_OPTIONS, - SYSTEMD_GETOPT_OPTIONS, - SHUTDOWN_GETOPT_OPTIONS, + const struct { + const char *name; + ArgType has_arg; + } options[] = { + { "log-level", required_argument }, + { "log-target", required_argument }, + { "log-color", optional_argument }, + { "log-location", optional_argument }, + { "log-time", optional_argument }, + { "unit", required_argument }, + { "system", no_argument, }, + { "user", no_argument, }, + { "test", no_argument, }, + { "no-pager", no_argument, }, + { "help", no_argument, }, + { "version", no_argument, }, + { "dump-configuration-items", no_argument, }, + { "dump-bus-properties", no_argument, }, + { "bus-introspect", required_argument }, + { "dump-core", optional_argument }, + { "crash-chvt", required_argument }, + { "crash-vt", required_argument }, + { "crash-shell", optional_argument }, + { "crash-reboot", optional_argument }, + { "crash-action", required_argument }, + { "confirm-spawn", optional_argument }, + { "show-status", optional_argument }, + { "deserialize", required_argument }, + { "switched-root", no_argument, }, + { "default-standard-output", required_argument }, + { "default-standard-error", required_argument }, + { "machine-id", required_argument }, + { "service-watchdogs", required_argument }, + { "exit-code", required_argument }, + { "timeout", required_argument }, }; - static const char *short_options = SYSTEMD_GETOPT_SHORT_OPTIONS; + const char *short_options = "hDbsz:"; _cleanup_strv_free_ char **filtered = NULL; int state, r; @@ -108,12 +139,10 @@ int proc_cmdline_filter_pid1_args(char **argv, char ***ret) { } int proc_cmdline(char **ret) { - const char *e; - assert(ret); /* For testing purposes it is sometimes useful to be able to override what we consider /proc/cmdline to be */ - e = secure_getenv("SYSTEMD_PROC_CMDLINE"); + const char *e = secure_getenv("SYSTEMD_PROC_CMDLINE"); if (e) return strdup_to(ret, e); @@ -124,13 +153,12 @@ int proc_cmdline(char **ret) { } static int proc_cmdline_strv_internal(char ***ret, bool filter_pid1_args) { - const char *e; int r; assert(ret); /* For testing purposes it is sometimes useful to be able to override what we consider /proc/cmdline to be */ - e = secure_getenv("SYSTEMD_PROC_CMDLINE"); + const char *e = secure_getenv("SYSTEMD_PROC_CMDLINE"); if (e) return strv_split_full(ret, e, NULL, EXTRACT_UNQUOTE|EXTRACT_RELAX|EXTRACT_RETAIN_ESCAPE); diff --git a/src/core/main.c b/src/core/main.c index 3e67186f33b..ce72d4431f9 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -977,6 +977,8 @@ static int parse_argv(int argc, char *argv[]) { int log_level_shift = getpid_cached() == 1 ? LOG_DEBUG - LOG_ERR : 0; OptionParser opts = { argc, argv, .log_level_shift = log_level_shift }; + /* Note: when new options are added here, also add them to the exclusion list in proc-cmdline.c! */ + FOREACH_OPTION(c, &opts) switch (c) { diff --git a/src/shutdown/shutdown.c b/src/shutdown/shutdown.c index 131550c46b2..c3c114a6674 100644 --- a/src/shutdown/shutdown.c +++ b/src/shutdown/shutdown.c @@ -61,7 +61,9 @@ static int parse_argv(int argc, char *argv[]) { assert(argv); /* The interface is: the verb must stay in argv[1]. Any extra positional arguments - * are warned about and ignored. See 4b5d8d0f22ae61ceb45a25391354ba53b43ee992. */ + * are warned about and ignored. See 4b5d8d0f22ae61ceb45a25391354ba53b43ee992. + * + * Note: when new options are added here, also add them to the exclusion list in proc-cmdline.c! */ OptionParser opts = { argc, argv, OPTION_PARSER_RETURN_POSITIONAL_ARGS }; int r;