Final batch of conversions to option and verb macros (#42127)

This commit is contained in:
Yu Watanabe
2026-05-17 03:50:48 +09:00
committed by GitHub
70 changed files with 208 additions and 895 deletions
-1
View File
@@ -38,7 +38,6 @@ CheckOptions:
# of them related to musl).
misc-include-cleaner.IgnoreHeaders: '
endian\.h;
getopt\.h;
sys/stat\.h;
sys/statvfs\.h;
sys/syscall\.h;
+1 -1
View File
@@ -716,7 +716,7 @@ static int run(int argc, char *argv[]) {
return log_oom();
}
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
+18 -22
View File
@@ -11,10 +11,11 @@
#include "device-util.h"
#include "escape.h"
#include "fileio.h"
#include "format-table.h"
#include "help-util.h"
#include "main-func.h"
#include "parse-util.h"
#include "percent-util.h"
#include "pretty-print.h"
#include "reboot-util.h"
#include "string-util.h"
#include "strv.h"
@@ -23,25 +24,22 @@
#define PCI_CLASS_GRAPHICS_CARD 0x30000
static int help(void) {
_cleanup_free_ char *link = NULL;
_cleanup_(table_unrefp) Table *verbs = NULL;
int r;
r = terminal_urlify_man("systemd-backlight", "8", &link);
r = verbs_get_help_table(&verbs);
if (r < 0)
return log_oom();
return r;
printf("%s save [backlight|leds]:DEVICE\n"
"%s load [backlight|leds]:DEVICE\n"
"\n%sSave and restore backlight brightness at shutdown and boot.%s\n\n"
" save Save current brightness\n"
" load Set brightness to be the previously saved value\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
program_invocation_short_name,
ansi_highlight(),
ansi_normal(),
link);
help_cmdline("COMMAND [backlight|leds]:DEVICE");
help_abstract("Save and restore backlight brightness at shutdown and boot.");
help_section("Commands");
r = table_print_or_warn(verbs);
if (r < 0)
return r;
help_man_page_reference("systemd-backlight", "8");
return 0;
}
@@ -555,6 +553,8 @@ static int device_new_from_arg(const char *s, sd_device **ret) {
return 1; /* Found. */
}
VERB(verb_load, "load", "[backlight|leds]:DEVICE", 2, 2, VERB_ONLINE_ONLY,
"Set brightness to be the previously saved value");
static int verb_load(int argc, char *argv[], uintptr_t _data, void *userdata) {
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
unsigned max_brightness, brightness, percent;
@@ -605,6 +605,8 @@ static int verb_load(int argc, char *argv[], uintptr_t _data, void *userdata) {
return 0;
}
VERB(verb_save, "save", "[backlight|leds]:DEVICE", 2, 2, VERB_ONLINE_ONLY,
"Save current brightness");
static int verb_save(int argc, char *argv[], uintptr_t _data, void *userdata) {
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
_cleanup_free_ char *path = NULL;
@@ -647,12 +649,6 @@ static int verb_save(int argc, char *argv[], uintptr_t _data, void *userdata) {
}
static int run(int argc, char *argv[]) {
static const Verb verbs[] = {
{ "load", 2, 2, VERB_ONLINE_ONLY, verb_load },
{ "save", 2, 2, VERB_ONLINE_ONLY, verb_save },
{}
};
log_setup();
if (argv_looks_like_help(argc, argv))
@@ -660,7 +656,7 @@ static int run(int argc, char *argv[]) {
umask(0022);
return dispatch_verb(argc, argv, verbs, NULL);
return dispatch_verb(strv_skip(argv, 1), /* userdata= */ NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -71,7 +71,7 @@ bool argv_looks_like_help(int argc, char **argv) {
char **l;
/* Scans the command line for indications the user asks for help. This is supposed to be called by
* tools that do not implement getopt() style command line parsing because they are not primarily
* tools that do not implement getopt()-style command line parsing because they are not primarily
* user-facing. Detects four ways of asking for help:
*
* 1. Passing zero arguments
+1 -2
View File
@@ -1,13 +1,12 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "memory-util.h"
#include "static-destruct.h"
void static_destruct_impl(const StaticDestructor *start, const StaticDestructor *end) {
if (!start)
return;
for (const StaticDestructor *d = ALIGN_PTR(start); d < end; d = ALIGN_PTR(d + 1))
for (const StaticDestructor *d = start; d < end; d++)
switch (d->type) {
case STATIC_DESTRUCTOR_SIMPLE:
d->simple.destroy(d->simple.data);
+2
View File
@@ -44,6 +44,8 @@ typedef struct StaticDestructor {
};
} StaticDestructor;
assert_cc(sizeof(StaticDestructor) % sizeof(void*) == 0);
#define STATIC_DESTRUCTOR_REGISTER(variable, func) \
_STATIC_DESTRUCTOR_REGISTER(UNIQ, variable, func)
+1 -1
View File
@@ -580,7 +580,7 @@ static int run(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"Marking a boot is only supported on EFI systems.");
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -917,7 +917,7 @@ static int run(int argc, char *argv[]) {
return log_oom();
}
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
+1 -1
View File
@@ -2324,7 +2324,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -1501,7 +1501,7 @@ static int run(int argc, char *argv[]) {
return log_oom();
}
r = dispatch_verb_with_args(args, NULL);
r = dispatch_verb(args, NULL);
if (units_active > 0)
printf("%s-- Notice: %d systemd-coredump@.service %s, output may be incomplete.%s\n",
+1 -1
View File
@@ -1478,7 +1478,7 @@ static int run(int argc, char *argv[]) {
if (arg_varlink)
return vl_server();
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
+1 -1
View File
@@ -2883,7 +2883,7 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+30 -25
View File
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <fcntl.h>
#include <getopt.h>
#include <linux/loop.h>
#include <stdio.h>
#include <stdlib.h>
@@ -132,11 +131,11 @@ static int help(void) {
if (r < 0)
return log_oom();
r = option_parser_get_help_table(&options);
r = option_parser_get_help_table_ns("systemd-dissect", &options);
if (r < 0)
return r;
r = option_parser_get_help_table_group("Commands", &commands);
r = option_parser_get_help_table_full("systemd-dissect", "Commands", &commands);
if (r < 0)
return r;
@@ -230,11 +229,13 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
OptionParser opts = { argc, argv };
OptionParser opts = { argc, argv, .namespace = "systemd-dissect" };
FOREACH_OPTION_OR_RETURN(c, &opts)
switch (c) {
OPTION_NAMESPACE("systemd-dissect"): {}
OPTION_COMMON_NO_PAGER:
arg_pager_flags |= PAGER_DISABLE;
break;
@@ -745,41 +746,45 @@ static int parse_argv(int argc, char *argv[]) {
static int parse_argv_as_mount_helper(int argc, char *argv[]) {
const char *options = NULL;
bool fake = false;
int c, r;
int r;
/* Implements util-linux "external helper" command line interface, as per mount(8) man page. */
while ((c = getopt(argc, argv, "sfnvN:o:t:")) >= 0) {
OptionParser opts = { argc, argv, .namespace = "mount.ddi" };
FOREACH_OPTION_OR_RETURN(c, &opts)
switch (c) {
case 'f':
OPTION_NAMESPACE("mount.ddi"): {}
OPTION_SHORT('f', NULL, /* help= */ NULL):
fake = true;
break;
case 'o':
options = optarg;
OPTION_SHORT('o', "OPTIONS", /* help= */ NULL):
options = opts.arg;
break;
case 't':
if (!streq(optarg, "ddi"))
log_debug("Unexpected file system type '%s', ignoring.", optarg);
OPTION_SHORT('t', "FSTYPE", /* help= */ NULL):
if (!streq(opts.arg, "ddi"))
log_debug("Unexpected file system type '%s', ignoring.", opts.arg);
break;
case 's': /* sloppy mount options */
case 'n': /* aka --no-mtab */
case 'v': /* aka --verbose */
log_debug("Ignoring option -%c, not implemented.", c);
OPTION_SHORT('s', NULL, /* help= */ NULL): {} /* sloppy mount options */
OPTION_SHORT('n', NULL, /* help= */ NULL): {} /* aka --no-mtab */
OPTION_SHORT('v', NULL, /* help= */ NULL): /* aka --verbose */
log_debug("Ignoring option -%c, not implemented.", opts.opt->short_code);
break;
case 'N': /* aka --namespace= */
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Option -%c is not implemented, refusing.", c);
case '?':
return -EINVAL;
OPTION_SHORT('N', "NS", /* help= */ NULL): /* aka --namespace= */
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"Option -%c is not implemented, refusing.",
opts.opt->short_code);
}
}
if (optind + 2 != argc)
char **args = option_parser_get_args(&opts);
size_t n_args = option_parser_get_n_args(&opts);
if (n_args != 2)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Expected an image file path and target directory as only argument.");
@@ -808,11 +813,11 @@ static int parse_argv_as_mount_helper(int argc, char *argv[]) {
if (fake)
return 0;
r = parse_path_argument(argv[optind], /* suppress_root= */ false, &arg_image);
r = parse_path_argument(args[0], /* suppress_root= */ false, &arg_image);
if (r < 0)
return r;
r = parse_path_argument(argv[optind+1], /* suppress_root= */ false, &arg_path);
r = parse_path_argument(args[1], /* suppress_root= */ false, &arg_path);
if (r < 0)
return r;
+1 -1
View File
@@ -365,7 +365,7 @@ static int run(int argc, char *argv[]) {
if (arg_varlink)
return varlink_service();
return dispatch_verb_with_args(args, /* userdata= */ NULL);
return dispatch_verb(args, /* userdata= */ NULL);
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
+1 -1
View File
@@ -5165,7 +5165,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, /* userdata= */ NULL);
return dispatch_verb(args, /* userdata= */ NULL);
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
+1 -1
View File
@@ -100,7 +100,7 @@ static int run(int argc, char **argv) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, /* userdata= */ NULL);
return dispatch_verb(args, /* userdata= */ NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -833,7 +833,7 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return bus_log_connect_error(r, arg_transport, RUNTIME_SCOPE_SYSTEM);
return dispatch_verb_with_args(args, bus);
return dispatch_verb(args, bus);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -125,7 +125,7 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -304,7 +304,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -292,7 +292,7 @@ static int run(int argc, char *argv[]) {
(void) ignore_signals(SIGPIPE);
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -400,7 +400,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -481,7 +481,7 @@ static int run(int argc, char *argv[]) {
(void) ignore_signals(SIGPIPE);
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -1260,7 +1260,7 @@ static int run(int argc, char *argv[]) {
(void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
return dispatch_verb_with_args(args, bus);
return dispatch_verb(args, bus);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -620,7 +620,7 @@ static int run(int argc, char *argv[]) {
(void) ignore_signals(SIGPIPE);
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
-29
View File
@@ -1,29 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
/* getopt() is provided both in getopt.h and unistd.h. Hence, we need to tentatively undefine it. */
#undef getopt
#include_next <getopt.h>
/* musl's getopt() always behaves POSIXLY_CORRECT mode, and stops parsing arguments when a non-option string
* found. Let's always use getopt_long(). */
int getopt_fix(int argc, char * const *argv, const char *optstring);
#define getopt(argc, argv, optstring) getopt_fix(argc, argv, optstring)
/* musl's getopt_long() behaves something different in handling optional arguments.
* ========
* $ journalctl _PID=1 _COMM=systemd --since 19:19:01 -n all --follow
* Failed to add match 'all': Invalid argument
* ========
* Here, we introduce getopt_long_fix() that reorders the passed arguments to make getopt_long() provided by
* musl works as what we expect. */
int getopt_long_fix(
int argc,
char * const *argv,
const char *optstring,
const struct option *longopts,
int *longindex);
#define getopt_long(argc, argv, optstring, longopts, longindex) \
getopt_long_fix(argc, argv, optstring, longopts, longindex)
-8
View File
@@ -1,16 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
/* getopt() is provided both in getopt.h and unistd.h. Hence, we need to tentatively undefine it. */
#undef getopt
#include_next <unistd.h>
/* musl's getopt() always behaves POSIXLY_CORRECT mode, and stops parsing arguments when a non-option string
* found. Let's always use getopt_long(). */
int getopt_fix(int argc, char * const *argv, const char *optstring);
#define getopt(argc, argv, optstring) getopt_fix(argc, argv, optstring)
int missing_close_range(unsigned first_fd, unsigned end_fd, unsigned flags);
#define close_range missing_close_range
+19 -18
View File
@@ -7,13 +7,15 @@
#include "argv-util.h"
#include "cryptsetup-util.h"
#include "fileio.h"
#include "format-table.h"
#include "help-util.h"
#include "integrity-util.h"
#include "log.h"
#include "main-func.h"
#include "path-util.h"
#include "pretty-print.h"
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
#include "time-util.h"
#include "verbs.h"
@@ -41,21 +43,22 @@ static const char* const dm_integrity_algorithm_table[_INTEGRITY_ALGORITHM_MAX]
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(dm_integrity_algorithm, IntegrityAlgorithm);
static int help(void) {
_cleanup_free_ char *link = NULL;
_cleanup_(table_unrefp) Table *verbs = NULL;
int r;
r = terminal_urlify_man("systemd-integritysetup@.service", "8", &link);
r = verbs_get_help_table(&verbs);
if (r < 0)
return log_oom();
return r;
printf("%s attach VOLUME DEVICE [HMAC_KEY_FILE|-] [OPTIONS]\n"
"%s detach VOLUME\n\n"
"Attach or detach an integrity protected block device.\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
program_invocation_short_name,
link);
help_cmdline("COMMAND ...");
help_abstract("Attach or detach an integrity protected block device.");
help_section("Commands");
r = table_print_or_warn(verbs);
if (r < 0)
return r;
help_man_page_reference("systemd-integritysetup@.service", "8");
return 0;
}
@@ -94,6 +97,8 @@ static const char *integrity_algorithm_select(const void *key_file_buf) {
return dm_integrity_algorithm_to_string(a);
}
VERB(verb_attach, "attach", "VOLUME DEVICE [HMAC_KEY_FILE|-] [OPTIONS]", 3, 5, 0,
"Attach an integrity protected block device");
static int verb_attach(int argc, char *argv[], uintptr_t _data, void *userdata) {
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
crypt_status_info status;
@@ -161,6 +166,8 @@ static int verb_attach(int argc, char *argv[], uintptr_t _data, void *userdata)
return 0;
}
VERB(verb_detach, "detach", "VOLUME", 2, 2, 0,
"Detach an integrity protected block device");
static int verb_detach(int argc, char *argv[], uintptr_t _data, void *userdata) {
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
int r;
@@ -203,13 +210,7 @@ static int run(int argc, char *argv[]) {
umask(0022);
static const Verb verbs[] = {
{ "attach", 3, 5, 0, verb_attach },
{ "detach", 2, 2, 0, verb_detach },
{}
};
return dispatch_verb(argc, argv, verbs, NULL);
return dispatch_verb(strv_skip(argv, 1), /* userdata= */ NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -1719,7 +1719,7 @@ static int run(int argc, char* argv[]) {
if (invoked_as(argv, "installkernel"))
return run_as_installkernel(args);
return dispatch_verb_with_args(args, /* userdata= */ NULL);
return dispatch_verb(args, /* userdata= */ NULL);
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
+1 -1
View File
@@ -415,7 +415,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
-100
View File
@@ -1,100 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <getopt.h>
#include <stdbool.h>
#include <string.h>
static int first_non_opt = 0, last_non_opt = 0;
static bool non_opt_found = false, dash_dash = false;
static void shift(char * const *argv, int start, int end) {
char **av = (char**) argv;
char *saved = av[end];
for (int i = end; i > start; i--)
av[i] = av[i - 1];
av[start] = saved;
}
static void exchange(int argc, char * const *argv) {
/* input:
*
* first_non_opt last_non_opt optind
* | | |
* v v v
* aaaaa bbbbb ccccc --prev-opt prev-opt-arg ddddd --next-opt
*
* output:
* first_non_opt last_non_opt optind
* | | |
* v v v
* --prev-opt prev-opt-arg aaaaa bbbbb ccccc ddddd --next-opt
*/
/* First, move previous arguments. */
int c = optind - 1 - last_non_opt;
if (c > 0) {
for (int i = 0; i < c; i++)
shift(argv, first_non_opt, optind - 1);
first_non_opt += c;
last_non_opt += c;
}
/* Then, skip entries that do not start with '-'. */
while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0')) {
if (!non_opt_found) {
first_non_opt = optind;
non_opt_found = true;
}
last_non_opt = optind;
optind++;
}
}
int getopt_long_fix(
int argc,
char * const *argv,
const char *optstring,
const struct option *longopts,
int *longindex) {
int r;
if (optind == 0 || first_non_opt == 0 || last_non_opt == 0) {
/* initialize musl's internal variables. */
(void) (getopt_long)(/* argc= */ -1, /* argv= */ NULL, /* optstring= */ NULL, /* longopts= */ NULL, /* longindex= */ NULL);
first_non_opt = last_non_opt = 1;
non_opt_found = dash_dash = false;
}
if (first_non_opt >= argc || last_non_opt >= argc || optind > argc || dash_dash)
return -1;
/* Do not shuffle arguments when optstring starts with '+' or '-'. */
if (!optstring || optstring[0] == '+' || optstring[0] == '-')
return (getopt_long)(argc, argv, optstring, longopts, longindex);
exchange(argc, argv);
if (optind < argc && strcmp(argv[optind], "--") == 0) {
if (first_non_opt < optind)
shift(argv, first_non_opt, optind);
first_non_opt++;
optind++;
dash_dash = true;
if (non_opt_found)
optind = first_non_opt;
return -1;
}
r = (getopt_long)(argc, argv, optstring, longopts, longindex);
if (r < 0 && non_opt_found)
optind = first_non_opt;
return r;
}
int getopt_fix(int argc, char * const *argv, const char *optstring) {
return getopt_long_fix(argc, argv, optstring, /* longopts= */ NULL, /* longindex= */ NULL);
}
-1
View File
@@ -6,7 +6,6 @@ endif
libc_wrapper_sources += files(
'crypt.c',
'getopt.c',
'printf.c',
'stdio.c',
'stdlib.c',
+8 -13
View File
@@ -83,22 +83,17 @@ static int bus_error_name_to_errno(const char *name) {
}
}
const sd_bus_error_map *elf_map = ALIGN_PTR(__start_SYSTEMD_BUS_ERROR_MAP);
while (elf_map < __stop_SYSTEMD_BUS_ERROR_MAP) {
assert_cc(sizeof(sd_bus_error_map) % sizeof(void*) == 0);
for (const sd_bus_error_map *m = __start_SYSTEMD_BUS_ERROR_MAP; m < __stop_SYSTEMD_BUS_ERROR_MAP; m++) {
/* For magic ELF error maps, the end marker might appear in the middle of things, since
* multiple maps might appear in the same section. Hence, let's skip over it, but realign
* the pointer to the next 8 byte boundary, which is the selected alignment for the arrays. */
if (elf_map->code == BUS_ERROR_MAP_END_MARKER) {
elf_map = ALIGN_PTR(elf_map + 1);
continue;
}
* multiple maps might appear in the same section. Skip over it. */
if (streq(elf_map->name, name)) {
assert(elf_map->code > 0);
return elf_map->code;
if (m->code != BUS_ERROR_MAP_END_MARKER &&
streq(m->name, name)) {
assert(m->code > 0);
return m->code;
}
elf_map++;
}
return EIO;
+4 -11
View File
@@ -128,19 +128,12 @@ extern const sd_bus_error_map __start_SYSTEMD_BUS_ERROR_MAP[];
extern const sd_bus_error_map __stop_SYSTEMD_BUS_ERROR_MAP[];
static int dump_mapping_table(void) {
const sd_bus_error_map *m;
printf("----- errno mappings ------\n");
m = ALIGN_PTR(__start_SYSTEMD_BUS_ERROR_MAP);
while (m < __stop_SYSTEMD_BUS_ERROR_MAP) {
for (const sd_bus_error_map *m = __start_SYSTEMD_BUS_ERROR_MAP; m < __stop_SYSTEMD_BUS_ERROR_MAP; m++) {
assert((uintptr_t) m % sizeof(void*) == 0);
if (m->code == BUS_ERROR_MAP_END_MARKER) {
m = ALIGN_PTR(m + 1);
continue;
}
printf("%s -> %i/%s\n", strna(m->name), m->code, ERRNO_NAME(m->code));
m++;
if (m->code != BUS_ERROR_MAP_END_MARKER)
printf("%s -> %i/%s\n", strna(m->name), m->code, ERRNO_NAME(m->code));
}
printf("---------------------------\n");
+1 -1
View File
@@ -519,7 +519,7 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return bus_log_connect_error(r, arg_transport, RUNTIME_SCOPE_SYSTEM);
return dispatch_verb_with_args(args, bus);
return dispatch_verb(args, bus);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -1680,7 +1680,7 @@ static int run(int argc, char *argv[]) {
(void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
return dispatch_verb_with_args(args, bus);
return dispatch_verb(args, bus);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -2656,7 +2656,7 @@ static int run(int argc, char *argv[]) {
(void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
return dispatch_verb_with_args(args, bus);
return dispatch_verb(args, bus);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -1126,7 +1126,7 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -213,7 +213,7 @@ static int run(int argc, char* argv[]) {
journal_browse_prepare();
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -120,7 +120,7 @@ static int run(int argc, char* argv[]) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -5505,7 +5505,7 @@ static int run(int argc, char *argv[]) {
return EXIT_SUCCESS;
}
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
+1 -1
View File
@@ -1455,7 +1455,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -362,7 +362,7 @@ static int parse_argv(int argc, char *argv[]) {
return version();
}
r = dispatch_verb_with_args(option_parser_get_args(&opts), NULL);
r = dispatch_verb(option_parser_get_args(&opts), NULL);
if (r < 0)
return r;
+1 -1
View File
@@ -886,7 +886,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+2 -2
View File
@@ -3761,7 +3761,7 @@ static int translate(const char *verb, const char *single_arg, char **args) {
STRV_FOREACH(a, args)
*p++ = *a;
return dispatch_verb_with_args(fake, /* userdata= */ NULL);
return dispatch_verb(fake, /* userdata= */ NULL);
}
static int compat_main(char **args) {
@@ -3883,7 +3883,7 @@ static int run(int argc, char **argv) {
if (compat)
return compat_main(args);
return dispatch_verb_with_args(args, /* userdata= */ NULL);
return dispatch_verb(args, /* userdata= */ NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -730,7 +730,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+3 -4
View File
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
#include "memory-util.h"
#include "shared-forward.h"
/* Option namespace/group explanation:
@@ -240,10 +239,10 @@ int option_parse(
/* Iterate over options. Don't forget to handle errors (negative c)! */
#define FOREACH_OPTION(c, state) \
for (int c; (c = option_parse(ALIGN_PTR(__start_SYSTEMD_OPTIONS), __stop_SYSTEMD_OPTIONS, state)) != 0; )
for (int c; (c = option_parse(__start_SYSTEMD_OPTIONS, __stop_SYSTEMD_OPTIONS, state)) != 0; )
#define FOREACH_OPTION_OR_RETURN(c, state) \
for (int c; (c = option_parse(ALIGN_PTR(__start_SYSTEMD_OPTIONS), __stop_SYSTEMD_OPTIONS, state)) != 0; ) \
for (int c; (c = option_parse(__start_SYSTEMD_OPTIONS, __stop_SYSTEMD_OPTIONS, state)) != 0; ) \
if (c < 0) \
return c; \
else
@@ -268,7 +267,7 @@ int _option_parser_get_help_table_full(
const char *group,
Table **ret);
#define option_parser_get_help_table_full(namespace, group, ret) \
_option_parser_get_help_table_full(ALIGN_PTR(__start_SYSTEMD_OPTIONS), __stop_SYSTEMD_OPTIONS, namespace, group, ret)
_option_parser_get_help_table_full(__start_SYSTEMD_OPTIONS, __stop_SYSTEMD_OPTIONS, namespace, group, ret)
#define option_parser_get_help_table_ns(ns, ret) \
option_parser_get_help_table_full(ns, /* group= */ NULL, ret)
#define option_parser_get_help_table_group(group, ret) \
+5 -5
View File
@@ -31,7 +31,7 @@ int parse_boolean_argument(const char *optname, const char *s, bool *ret) {
*ret = r;
return r;
} else {
/* s may be NULL. This is controlled by getopt_long() parameters. */
/* s may be NULL. This is controlled by OPTION flags. */
if (ret)
*ret = true;
return true;
@@ -42,10 +42,10 @@ int parse_tristate_argument_with_auto(const char *optname, const char *s, int *r
int r;
assert(optname);
assert(s); /* We refuse NULL optarg here, since that would be ambiguous on cmdline:
for --enable-a[=BOOL], --enable-a is intuitively interpreted as true rather than "auto"
(parse_boolean_argument() does exactly that). IOW, tristate options should require
arguments. */
assert(s); /* We refuse NULL arg here, since that would be ambiguous on cmdline: for
* --enable-a[=BOOL], --enable-a is intuitively interpreted as true rather than "auto"
* (parse_boolean_argument() does exactly that). IOW, tristate options should require
* arguments. */
r = parse_tristate_full(s, "auto", ret);
if (r < 0)
+2 -4
View File
@@ -380,20 +380,18 @@ int run_test_table(const TestFunc *start, const TestFunc *end) {
_cleanup_strv_free_ char **tests = NULL;
int r = EXIT_SUCCESS;
bool ran = false;
const char *e;
if (!start)
return r;
e = getenv("TESTFUNCS");
const char *e = getenv("TESTFUNCS");
if (e) {
r = strv_split_full(&tests, e, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
if (r < 0)
return log_error_errno(r, "Failed to parse $TESTFUNCS: %m");
}
for (const TestFunc *t = ALIGN_PTR(start); t + 1 <= end; t = ALIGN_PTR(t + 1)) {
for (const TestFunc *t = start; t + 1 <= end; t++) {
if (tests && !strv_contains(tests, t->name))
continue;
+8 -18
View File
@@ -1,7 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <getopt.h>
#include "env-util.h"
#include "format-table.h"
#include "log.h"
@@ -66,6 +64,9 @@ static bool verb_is_metadata(const Verb *verb) {
const Verb* verbs_find_verb(const char *name, const Verb verbs[], const Verb verbs_end[]) {
assert(verbs);
assert(verbs_end > verbs);
assert((uintptr_t) verbs % sizeof(void*) == 0);
assert(verbs[0].verb);
for (const Verb *verb = verbs; verb < verbs_end; verb++) {
if (verb_is_metadata(verb))
@@ -79,11 +80,12 @@ const Verb* verbs_find_verb(const char *name, const Verb verbs[], const Verb ver
return NULL;
}
int _dispatch_verb_with_args(char **args, const Verb verbs[], const Verb verbs_end[], void *userdata) {
int _dispatch_verb(char **args, const Verb verbs[], const Verb verbs_end[], void *userdata) {
int r;
assert(verbs);
assert(verbs_end > verbs);
assert((uintptr_t) verbs % sizeof(void*) == 0);
assert(verbs[0].verb);
const char *name = args ? args[0] : NULL;
@@ -146,21 +148,6 @@ int _dispatch_verb_with_args(char **args, const Verb verbs[], const Verb verbs_e
return verb->dispatch(left, args, verb->data, userdata);
}
int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) {
/* getopt wrapper for _dispatch_verb_with_args.
* TBD: remove this function when all programs with verbs have been converted. */
assert(argc >= 0);
assert(argv);
assert(argc >= optind);
size_t n = 0;
while (verbs[n].verb)
n++;
return _dispatch_verb_with_args(strv_skip(argv, optind), verbs, verbs + n, userdata);
}
#define VERB_SYNOPSIS_WIDTH_SANE 25
static const char* find_point_to_break(const char *s, size_t max_width) {
@@ -234,6 +221,9 @@ int _verbs_get_help_table(
Table **ret) {
int r;
assert(verbs);
assert(verbs_end > verbs);
assert((uintptr_t) verbs % sizeof(void*) == 0);
assert(ret);
_cleanup_(table_unrefp) Table *table = table_new("verb", "help");
+4 -6
View File
@@ -79,11 +79,9 @@ bool should_bypass(const char *env_prefix);
const Verb* verbs_find_verb(const char *name, const Verb verbs[], const Verb verbs_end[]);
int _dispatch_verb_with_args(char **args, const Verb verbs[], const Verb verbs_end[], void *userdata);
#define dispatch_verb_with_args(args, userdata) \
_dispatch_verb_with_args(args, ALIGN_PTR(__start_SYSTEMD_VERBS), __stop_SYSTEMD_VERBS, userdata)
int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata);
int _dispatch_verb(char **args, const Verb verbs[], const Verb verbs_end[], void *userdata);
#define dispatch_verb(args, userdata) \
_dispatch_verb(args, __start_SYSTEMD_VERBS, __stop_SYSTEMD_VERBS, userdata)
int _verbs_get_help_table(
const Verb verbs[],
@@ -91,7 +89,7 @@ int _verbs_get_help_table(
const char *group,
Table **ret);
#define verbs_get_help_table_group(group, ret) \
_verbs_get_help_table(ALIGN_PTR(__start_SYSTEMD_VERBS), __stop_SYSTEMD_VERBS, group, ret)
_verbs_get_help_table(__start_SYSTEMD_VERBS, __stop_SYSTEMD_VERBS, group, ret)
#define verbs_get_help_table(ret) \
verbs_get_help_table_group(/* group= */ NULL, ret)
+1 -1
View File
@@ -760,7 +760,7 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
return dispatch_verb_with_args(args, sleep_config);
return dispatch_verb(args, sleep_config);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -224,7 +224,7 @@ static int run(int argc, char* argv[]) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+33 -28
View File
@@ -2,7 +2,6 @@
#include "sd-varlink.h"
#include <getopt.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -59,7 +58,7 @@ static int help(void) {
return r;
_cleanup_(table_unrefp) Table *options = NULL;
r = option_parser_get_help_table(&options);
r = option_parser_get_help_table_ns("storagectl", &options);
if (r < 0)
return r;
@@ -406,10 +405,12 @@ static int parse_argv(int argc, char *argv[], char ***remaining_args) {
assert(argv);
assert(remaining_args);
OptionParser opts = { argc, argv };
OptionParser opts = { argc, argv, .namespace = "storagectl" };
FOREACH_OPTION_OR_RETURN(c, &opts)
switch (c) {
OPTION_NAMESPACE("storagectl"): {}
OPTION_COMMON_HELP:
return help();
@@ -448,7 +449,7 @@ static int parse_argv(int argc, char *argv[], char ***remaining_args) {
}
static int run_as_mount_helper(int argc, char *argv[]) {
int c, r;
int r;
/* Implements util-linux "external helper" command line interface, as per mount(8) man page.
*
@@ -461,51 +462,55 @@ static int run_as_mount_helper(int argc, char *argv[]) {
const char *fstype = NULL, *options = NULL;
bool fake = false;
while ((c = getopt(argc, argv, "sfnvN:o:t:")) >= 0) {
OptionParser opts = { argc, argv, .namespace = "mount.storage" };
FOREACH_OPTION_OR_RETURN(c, &opts)
switch (c) {
case 'f':
OPTION_NAMESPACE("mount.storage"): {}
OPTION_SHORT('f', NULL, /* help= */ NULL):
fake = true;
break;
case 'o':
options = optarg;
OPTION_SHORT('o', "OPTIONS", /* help= */ NULL):
options = opts.arg;
break;
case 't':
fstype = startswith(optarg, "storage.");
OPTION_SHORT('t', "FSTYPE", /* help= */ NULL):
fstype = startswith(opts.arg, "storage.");
if (fstype) {
/* Paranoia: don't allow "storage.storage.storage.…" chains... */
if (startswith(fstype, "storage.") || streq(fstype, "storage"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Refusing nested storage volumes.");
} else if (!streq(optarg, "storage"))
log_warning("Unexpected file system type '%s', ignoring.", optarg);
} else if (!streq(opts.arg, "storage"))
log_warning("Unexpected file system type '%s', ignoring.", opts.arg);
break;
case 's': /* sloppy mount options */
case 'n': /* aka --no-mtab */
case 'v': /* aka --verbose */
log_debug("Ignoring option -%c, not implemented.", c);
OPTION_SHORT('s', NULL, /* help= */ NULL): {} /* sloppy mount options */
OPTION_SHORT('n', NULL, /* help= */ NULL): {} /* aka --no-mtab */
OPTION_SHORT('v', NULL, /* help= */ NULL): /* aka --verbose */
log_debug("Ignoring option -%c, not implemented.", opts.opt->short_code);
break;
case 'N': /* aka --namespace= */
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Option -%c is not implemented, refusing.", c);
case '?':
return -EINVAL;
OPTION_SHORT('N', "NS", /* help= */ NULL): /* aka --namespace= */
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"Option -%c is not implemented, refusing.",
opts.opt->short_code);
}
}
if (optind + 2 != argc)
char **args = option_parser_get_args(&opts);
size_t n_args = option_parser_get_n_args(&opts);
if (n_args != 2)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Expected a storage volume specification and target directory as only arguments.");
const char *colon = strchr(argv[optind], ':');
const char *colon = strchr(args[0], ':');
if (!colon)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid storage volume specification, refusing: %s", argv[optind]);
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid storage volume specification, refusing: %s", args[0]);
_cleanup_free_ char *provider = strndup(argv[optind], colon - argv[optind]);
_cleanup_free_ char *provider = strndup(args[0], colon - args[0]);
if (!provider)
return log_oom();
if (!storage_provider_name_is_valid(provider))
@@ -518,7 +523,7 @@ static int run_as_mount_helper(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid storage volume name: %s", name);
_cleanup_free_ char *path = NULL;
r = parse_path_argument(argv[optind+1], /* suppress_root= */ false, &path);
r = parse_path_argument(args[1], /* suppress_root= */ false, &path);
if (r < 0)
return r;
@@ -735,7 +740,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, /* userdata= */ NULL);
return dispatch_verb(args, /* userdata= */ NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -3048,7 +3048,7 @@ static int run(int argc, char *argv[]) {
return EXIT_SUCCESS;
}
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+4 -4
View File
@@ -1112,13 +1112,13 @@ VERB_SCOPE(, verb_start, "condrestart", NULL, 2, VERB_ANY,
VERB_SCOPE(, verb_is_active, "check", NULL, 2, VERB_ANY, VERB_ONLINE_ONLY, /* help= */ NULL); /* deprecated alias of is-active */
int systemctl_main(char **args) {
const Verb *verb = verbs_find_verb(args[0],
ALIGN_PTR(__start_SYSTEMD_VERBS),
__stop_SYSTEMD_VERBS);
assert((uintptr_t) __start_SYSTEMD_VERBS % sizeof(void*) == 0);
const Verb *verb = verbs_find_verb(args[0], __start_SYSTEMD_VERBS, __stop_SYSTEMD_VERBS);
if (verb && (verb->flags & VERB_ONLINE_ONLY) && arg_root)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Verb '%s' cannot be used with --root= or --image=.",
args[0] ?: verb->verb);
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
+1 -1
View File
@@ -2010,7 +2010,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
+1 -1
View File
@@ -1757,7 +1757,7 @@ static int run(int argc, char *argv[]) {
(void) sd_bus_set_allow_interactive_authorization(bus, true);
return dispatch_verb_with_args(args, bus);
return dispatch_verb(args, bus);
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
-1
View File
@@ -111,7 +111,6 @@ simple_tests += files(
'test-format-util.c',
'test-fs-util.c',
'test-fstab-util.c',
'test-getopt.c',
'test-glob-util.c',
'test-gpt.c',
'test-gunicode.c',
-516
View File
@@ -1,516 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <getopt.h>
#include "strv.h"
#include "tests.h"
typedef struct Entry {
int opt;
const char *argument;
const char *nextarg;
} Entry;
static void test_getopt_long_one(
char **argv,
const char *optstring,
const struct option *longopts,
const Entry *entries,
char **remaining) {
_cleanup_free_ char *joined = strv_join(argv, ", ");
log_debug("/* %s(%s) */", __func__, joined);
_cleanup_free_ char *saved_argv0 = NULL;
ASSERT_NOT_NULL(saved_argv0 = strdup(argv[0]));
int c, argc = strv_length(argv);
size_t i = 0, n_entries = 0;
for (const Entry *e = entries; e && e->opt != 0; e++)
n_entries++;
optind = 0;
while ((c = getopt_long(argc, argv, optstring, longopts, NULL)) >= 0) {
if (c < 0x100)
log_debug("%c: %s", c, strna(optarg));
else
log_debug("0x%x: %s", (unsigned) c, strna(optarg));
ASSERT_LT(i, n_entries);
ASSERT_EQ(c, entries[i].opt);
ASSERT_STREQ(optarg, entries[i].argument);
if (entries[i].nextarg)
ASSERT_STREQ(argv[optind], entries[i].nextarg);
i++;
}
ASSERT_EQ(i, n_entries);
ASSERT_LE(optind, argc);
ASSERT_EQ(argc - optind, (int) strv_length(remaining));
for (int j = optind; j < argc; j++)
ASSERT_STREQ(argv[j], remaining[j - optind]);
ASSERT_STREQ(argv[0], saved_argv0);
}
TEST(getopt_long) {
enum {
ARG_VERSION = 0x100,
ARG_REQUIRED,
ARG_OPTIONAL,
};
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version" , no_argument, NULL, ARG_VERSION },
{ "required1", required_argument, NULL, 'r' },
{ "required2", required_argument, NULL, ARG_REQUIRED },
{ "optional1", optional_argument, NULL, 'o' },
{ "optional2", optional_argument, NULL, ARG_OPTIONAL },
{},
};
test_getopt_long_one(STRV_MAKE("arg0"),
"hr:o::", options,
NULL,
NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"string3",
"string4"),
"hr:o::", options,
NULL,
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"--",
"string1",
"--help",
"-h",
"string4"),
"hr:o::", options,
NULL,
STRV_MAKE("string1",
"--help",
"-h",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"--",
"--",
"string4"),
"hr:o::", options,
NULL,
STRV_MAKE("string1",
"string2",
"--",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"string3",
"string4",
"--"),
"hr:o::", options,
NULL,
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"--help"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"-h"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"--help",
"string1",
"string2",
"string3",
"string4"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"-h",
"string1",
"string2",
"string3",
"string4"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"--help",
"string3",
"string4"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"-h",
"string3",
"string4"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"string3",
"string4",
"--help"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"string3",
"string4",
"-h"),
"hr:o::", options,
(Entry[]) {
{ 'h', NULL },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4"));
test_getopt_long_one(STRV_MAKE("arg0",
"--required1", "reqarg1"),
"hr:o::", options,
(Entry[]) {
{ 'r', "reqarg1" },
{}
},
NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"-r", "reqarg1"),
"hr:o::", options,
(Entry[]) {
{ 'r', "reqarg1" },
{}
},
NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"string2",
"-r", "reqarg1"),
"hr:o::", options,
(Entry[]) {
{ 'r', "reqarg1" },
{}
},
STRV_MAKE("string1",
"string2"));
test_getopt_long_one(STRV_MAKE("arg0",
"--optional1=optarg1"),
"hr:o::", options,
(Entry[]) {
{ 'o', "optarg1" },
{}
},
NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"--optional1", "string1"),
"hr:o::", options,
(Entry[]) {
{ 'o', NULL, "string1" },
{}
},
STRV_MAKE("string1"));
test_getopt_long_one(STRV_MAKE("arg0",
"-ooptarg1"),
"hr:o::", options,
(Entry[]) {
{ 'o', "optarg1" },
{}
}, NULL);
test_getopt_long_one(STRV_MAKE("arg0",
"-o", "string1"),
"hr:o::", options,
(Entry[]) {
{ 'o', NULL, "string1" },
{}
},
STRV_MAKE("string1"));
test_getopt_long_one(STRV_MAKE("arg0",
"string1",
"--help",
"--version",
"string2",
"--required1", "reqarg1",
"--required2", "reqarg2",
"--required1=reqarg3",
"--required2=reqarg4",
"string3",
"--optional1", "string4",
"--optional2", "string5",
"--optional1=optarg1",
"--optional2=optarg2",
"-h",
"-r", "reqarg5",
"-rreqarg6",
"-ooptarg3",
"-o",
"string6",
"-o",
"-h",
"-o",
"--help",
"string7",
"-hooptarg4",
"-hrreqarg6",
"--",
"--help",
"--required1",
"--optional1"),
"hr:o::", options,
(Entry[]) {
{ 'h' },
{ ARG_VERSION },
{ 'r', "reqarg1" },
{ ARG_REQUIRED, "reqarg2" },
{ 'r', "reqarg3" },
{ ARG_REQUIRED, "reqarg4" },
{ 'o', NULL, "string4" },
{ ARG_OPTIONAL, NULL, "string5" },
{ 'o', "optarg1" },
{ ARG_OPTIONAL, "optarg2" },
{ 'h' },
{ 'r', "reqarg5" },
{ 'r', "reqarg6" },
{ 'o', "optarg3" },
{ 'o', NULL, "string6" },
{ 'o', NULL, "-h" },
{ 'h' },
{ 'o', NULL, "--help" },
{ 'h' },
{ 'h' },
{ 'o', "optarg4" },
{ 'h' },
{ 'r', "reqarg6" },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string4",
"string5",
"string6",
"string7",
"--help",
"--required1",
"--optional1"));
}
static void test_getopt_one(
char **argv,
const char *optstring,
const Entry *entries,
char **remaining) {
_cleanup_free_ char *joined = strv_join(argv, ", ");
log_debug("/* %s(%s) */", __func__, joined);
_cleanup_free_ char *saved_argv0 = NULL;
ASSERT_NOT_NULL(saved_argv0 = strdup(argv[0]));
int c, argc = strv_length(argv);
size_t i = 0, n_entries = 0;
for (const Entry *e = entries; e && e->opt != 0; e++)
n_entries++;
optind = 0;
while ((c = getopt(argc, argv, optstring)) >= 0) {
log_debug("%c: %s", c, strna(optarg));
ASSERT_LT(i, n_entries);
ASSERT_EQ(c, entries[i].opt);
ASSERT_STREQ(optarg, entries[i].argument);
if (entries[i].nextarg)
ASSERT_STREQ(argv[optind], entries[i].nextarg);
i++;
}
ASSERT_EQ(i, n_entries);
ASSERT_LE(optind, argc);
ASSERT_EQ(argc - optind, (int) strv_length(remaining));
for (int j = optind; j < argc; j++)
ASSERT_STREQ(argv[j], remaining[j - optind]);
ASSERT_STREQ(argv[0], saved_argv0);
}
TEST(getopt) {
test_getopt_one(STRV_MAKE("arg0"),
"hr:o::",
NULL,
NULL);
test_getopt_one(STRV_MAKE("arg0",
"string1",
"string2"),
"hr:o::",
NULL,
STRV_MAKE("string1",
"string2"));
test_getopt_one(STRV_MAKE("arg0",
"-h"),
"hr:o::",
(Entry[]) {
{ 'h', NULL },
{}
},
NULL);
test_getopt_one(STRV_MAKE("arg0",
"-r", "reqarg1"),
"hr:o::",
(Entry[]) {
{ 'r', "reqarg1" },
{}
},
NULL);
test_getopt_one(STRV_MAKE("arg0",
"string1",
"string2",
"-r", "reqarg1"),
"hr:o::",
(Entry[]) {
{ 'r', "reqarg1" },
{}
},
STRV_MAKE("string1",
"string2"));
test_getopt_one(STRV_MAKE("arg0",
"-ooptarg1"),
"hr:o::",
(Entry[]) {
{ 'o', "optarg1" },
{}
},
NULL);
test_getopt_one(STRV_MAKE("arg0",
"-o", "string1"),
"hr:o::",
(Entry[]) {
{ 'o', NULL, "string1" },
{}
},
STRV_MAKE("string1"));
test_getopt_one(STRV_MAKE("arg0",
"string1",
"string2",
"string3",
"-h",
"-r", "reqarg5",
"-rreqarg6",
"-ooptarg3",
"-o",
"string6",
"-o",
"-h",
"-o",
"string7",
"-hooptarg4",
"-hrreqarg6"),
"hr:o::",
(Entry[]) {
{ 'h' },
{ 'r', "reqarg5" },
{ 'r', "reqarg6" },
{ 'o', "optarg3" },
{ 'o', NULL, "string6" },
{ 'o', NULL, "-h" },
{ 'h' },
{ 'o', NULL, "string7" },
{ 'h' },
{ 'o', "optarg4" },
{ 'h' },
{ 'r', "reqarg6" },
{}
},
STRV_MAKE("string1",
"string2",
"string3",
"string6",
"string7"));
}
DEFINE_TEST_MAIN(LOG_DEBUG);
+1 -4
View File
@@ -1,7 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <getopt.h>
#include "strv.h"
#include "tests.h"
#include "verbs.h"
@@ -11,8 +9,7 @@ static int noop_dispatcher(int argc, char *argv[], uintptr_t _data, void *userda
}
#define test_dispatch_one(argv, verbs, expected) \
optind = 0; \
assert_se(dispatch_verb(strv_length(argv), argv, verbs, NULL) == expected);
assert_se(_dispatch_verb(argv, verbs, verbs + ELEMENTSOF(verbs) - 1, NULL) == expected);
TEST(verbs) {
static const Verb verbs[] = {
+1 -1
View File
@@ -1028,7 +1028,7 @@ static int run(int argc, char *argv[]) {
(void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
return dispatch_verb_with_args(args, bus);
return dispatch_verb(args, bus);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -308,7 +308,7 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
-1
View File
@@ -5,7 +5,6 @@
* Logic based on Hannes Reinecke's shell script.
*/
#include <getopt.h>
#include <linux/usb/ch11.h>
#include <stdio.h>
#include <stdlib.h>
-3
View File
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <getopt.h>
#include <stdio.h>
#include "alloc-util.h"
@@ -128,8 +127,6 @@ int udev_builtin_run(UdevEvent *event, UdevBuiltinCommand cmd, const char *comma
if (r < 0)
return r;
/* we need '0' here to reset the internal state */
optind = 0;
return builtins[cmd]->cmd(event, strv_length(argv), argv);
}
-2
View File
@@ -1,7 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <getopt.h>
#include "sd-bus.h"
#include "alloc-util.h"
+1 -1
View File
@@ -115,7 +115,7 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
+4 -7
View File
@@ -10,6 +10,7 @@
#include "libaudit-util.h"
#include "log.h"
#include "main-func.h"
#include "strv.h"
#include "time-util.h"
#include "utmp-wtmp.h"
#include "verbs.h"
@@ -51,6 +52,7 @@ static int get_startup_monotonic_time(Context *c, usec_t *ret) {
return 0;
}
VERB_NOARG(verb_on_reboot, "reboot", /* help= */ NULL);
static int verb_on_reboot(int argc, char *argv[], uintptr_t _data, void *userdata) {
Context *c = ASSERT_PTR(userdata);
usec_t t = 0, boottime;
@@ -80,6 +82,7 @@ static int verb_on_reboot(int argc, char *argv[], uintptr_t _data, void *userdat
return q;
}
VERB_NOARG(verb_on_shutdown, "shutdown", /* help= */ NULL);
static int verb_on_shutdown(int argc, char *argv[], uintptr_t _data, void *userdata) {
int r, q = 0;
@@ -102,12 +105,6 @@ static int verb_on_shutdown(int argc, char *argv[], uintptr_t _data, void *userd
}
static int run(int argc, char *argv[]) {
static const Verb verbs[] = {
{ "reboot", 1, 1, 0, verb_on_reboot },
{ "shutdown", 1, 1, 0, verb_on_shutdown },
{}
};
_cleanup_(context_clear) Context c = {
.audit_fd = -EBADF,
};
@@ -118,7 +115,7 @@ static int run(int argc, char *argv[]) {
c.audit_fd = open_audit_fd_or_warn();
return dispatch_verb(argc, argv, verbs, &c);
return dispatch_verb(strv_skip(argv, 1), &c);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -1874,7 +1874,7 @@ static int run(int argc, char *argv[]) {
} else
assert_se(unsetenv("SYSTEMD_ONLY_USERDB") == 0);
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+1 -1
View File
@@ -1318,7 +1318,7 @@ static int run(int argc, char *argv[]) {
if (r <= 0)
return r;
return dispatch_verb_with_args(args, NULL);
return dispatch_verb(args, NULL);
}
DEFINE_MAIN_FUNCTION(run);
+18 -18
View File
@@ -10,14 +10,15 @@
#include "cryptsetup-util.h"
#include "extract-word.h"
#include "fileio.h"
#include "format-table.h"
#include "fstab-util.h"
#include "help-util.h"
#include "hexdecoct.h"
#include "log.h"
#include "main-func.h"
#include "parse-util.h"
#include "path-util.h"
#include "pcrextend-util.h"
#include "pretty-print.h"
#include "string-util.h"
#include "strv.h"
#include "tpm2-util.h"
@@ -50,21 +51,22 @@ STATIC_DESTRUCTOR_REGISTER(arg_root_hash_signature, freep);
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_measure_nvpcr, freep);
static int help(void) {
_cleanup_free_ char *link = NULL;
_cleanup_(table_unrefp) Table *verbs = NULL;
int r;
r = terminal_urlify_man("systemd-veritysetup@.service", "8", &link);
r = verbs_get_help_table(&verbs);
if (r < 0)
return log_oom();
return r;
printf("%s attach VOLUME DATADEVICE HASHDEVICE ROOTHASH [OPTIONS]\n"
"%s detach VOLUME\n\n"
"Attach or detach a verity protected block device.\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
program_invocation_short_name,
link);
help_cmdline("COMMAND ...");
help_abstract("Attach or detach a verity protected block device.");
help_section("Commands");
r = table_print_or_warn(verbs);
if (r < 0)
return r;
help_man_page_reference("systemd-veritysetup@.service", "8");
return 0;
}
@@ -315,6 +317,8 @@ static int parse_options(const char *options) {
return r;
}
VERB(verb_attach, "attach", "VOLUME DATADEVICE HASHDEVICE ROOTHASH [OPTIONS]", 5, 6, 0,
"Attach a verity protected block device");
static int verb_attach(int argc, char *argv[], uintptr_t _data, void *userdata) {
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
_cleanup_free_ void *rh = NULL;
@@ -449,6 +453,8 @@ static int verb_attach(int argc, char *argv[], uintptr_t _data, void *userdata)
return 0;
}
VERB(verb_detach, "detach", "VOLUME", 2, 2, 0,
"Detach a verity protected block device");
static int verb_detach(int argc, char *argv[], uintptr_t _data, void *userdata) {
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
int r;
@@ -491,13 +497,7 @@ static int run(int argc, char *argv[]) {
umask(0022);
static const Verb verbs[] = {
{ "attach", 5, 6, 0, verb_attach },
{ "detach", 2, 2, 0, verb_detach },
{}
};
return dispatch_verb(argc, argv, verbs, NULL);
return dispatch_verb(strv_skip(argv, 1), /* userdata= */ NULL);
}
DEFINE_MAIN_FUNCTION(run);