]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic: fold getopt-defs.h into proc-cmdline.c
authorZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Thu, 14 May 2026 17:44:22 +0000 (19:44 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Fri, 15 May 2026 07:26:48 +0000 (09:26 +0200)
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.

TODO.md
src/basic/getopt-defs.h [deleted file]
src/basic/proc-cmdline.c
src/core/main.c
src/shutdown/shutdown.c

diff --git a/TODO.md b/TODO.md
index fe13b0b24dff4c6ab306e894dfa4b6b24c6bc0f1..d9d9e7dd9fc93233c44fe6d5b9347dc813848435 100644 (file)
--- 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 (file)
index 9abef6f..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#pragma once
-
-#include <getopt.h>
-
-#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      }
index eb61b0bc554e2f8f74f7ae54fb45391a22343452..4de3480ff0255db7ae18ffd29e21e3ed4e1ccff0 100644 (file)
@@ -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"
 #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);
 
index 3e67186f33b4c441de7dd4e09a6f0e8d88e7657a..ce72d4431f90623b444db8985323a32017df308d 100644 (file)
@@ -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) {
 
index 131550c46b20d6442a93505d8881cbed6f543828..c3c114a6674c497a6937a81b41298c841b7d5a8b 100644 (file)
@@ -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;