diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index d76c09b520..fc85388f30 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -472,10 +472,9 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_RECURSIVE_ERRORS: - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(recursive_errors, RecursiveErrors, _RECURSIVE_ERRORS_MAX); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(recursive_errors, RecursiveErrors, _RECURSIVE_ERRORS_MAX); + r = recursive_errors_from_string(optarg); if (r < 0) return log_error_errno(r, "Unknown mode passed to --recursive-errors='%s'.", optarg); diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index 9b56af7beb..19ad6f68a9 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -20,6 +20,7 @@ #include "process-util.h" #include "procfs-util.h" #include "sort-util.h" +#include "string-table.h" #include "terminal-util.h" #include "time-util.h" #include "virt.h" @@ -54,6 +55,23 @@ typedef enum PidsCount { COUNT_PIDS, /* most, requires pids controller */ } PidsCount; +typedef enum { + ORDER_PATH, + ORDER_TASKS, + ORDER_CPU, + ORDER_MEMORY, + ORDER_IO, + _ORDER_MAX, + _ORDER_INVALID = -EINVAL, +} Order; + +typedef enum { + CPU_PERCENTAGE, + CPU_TIME, + _CPU_MAX, + _CPU_INVALID = -EINVAL, +} CPUType; + static unsigned arg_depth = 3; static unsigned arg_iterations = UINT_MAX; static bool arg_batch = false; @@ -63,21 +81,26 @@ static char* arg_machine = NULL; static char* arg_root = NULL; static bool arg_recursive = true; static bool arg_recursive_unset = false; - static PidsCount arg_count = COUNT_PIDS; +static Order arg_order = ORDER_CPU; +static CPUType arg_cpu_type = CPU_PERCENTAGE; -static enum { - ORDER_PATH, - ORDER_TASKS, - ORDER_CPU, - ORDER_MEMORY, - ORDER_IO, -} arg_order = ORDER_CPU; +static const char *order_table[_ORDER_MAX] = { + [ORDER_PATH] = "path", + [ORDER_TASKS] = "tasks", + [ORDER_CPU] = "cpu", + [ORDER_MEMORY] = "memory", + [ORDER_IO] = "io", +}; -static enum { - CPU_PERCENT, - CPU_TIME, -} arg_cpu_type = CPU_PERCENT; +DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(order, Order); + +static const char *cpu_type_table[_CPU_MAX] = { + [CPU_PERCENTAGE] = "percentage", + [CPU_TIME] = "time", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(cpu_type, CPUType); static Group *group_free(Group *g) { if (!g) @@ -507,7 +530,7 @@ static int group_compare(Group * const *a, Group * const *b) { break; case ORDER_CPU: - if (arg_cpu_type == CPU_PERCENT) { + if (arg_cpu_type == CPU_PERCENTAGE) { if (x->cpu_valid && y->cpu_valid) { r = CMP(y->cpu_fraction, x->cpu_fraction); if (r != 0) @@ -557,6 +580,12 @@ static int group_compare(Group * const *a, Group * const *b) { return -1; else if (y->io_valid) return 1; + + break; + + case _ORDER_MAX: + case _ORDER_INVALID: + assert_not_reached(); } return path_compare(x->path, y->path); @@ -595,7 +624,7 @@ static void display(Hashmap *a) { if (on_tty()) { const char *on, *off; - int cpu_len = arg_cpu_type == CPU_PERCENT ? 6 : maxtcpu; + int cpu_len = arg_cpu_type == CPU_PERCENTAGE ? 6 : maxtcpu; path_columns = columns() - 36 - cpu_len; if (path_columns < 10) @@ -613,7 +642,7 @@ static void display(Hashmap *a) { arg_order == ORDER_TASKS ? off : "", arg_order == ORDER_CPU ? on : "", cpu_len, - arg_cpu_type == CPU_PERCENT ? "%CPU" : "CPU Time", + arg_cpu_type == CPU_PERCENTAGE ? "%CPU" : "CPU Time", arg_order == ORDER_CPU ? off : "", arg_order == ORDER_MEMORY ? on : "", "Memory", arg_order == ORDER_MEMORY ? off : "", @@ -643,7 +672,7 @@ static void display(Hashmap *a) { else fputs(" -", stdout); - if (arg_cpu_type == CPU_PERCENT) { + if (arg_cpu_type == CPU_PERCENTAGE) { if (g->cpu_valid) printf(" %6.1f", g->cpu_fraction*100); else @@ -739,12 +768,9 @@ static int parse_argv(int argc, char *argv[]) { case ARG_CPU_TYPE: if (optarg) { - if (streq(optarg, "time")) - arg_cpu_type = CPU_TIME; - else if (streq(optarg, "percentage")) - arg_cpu_type = CPU_PERCENT; - else - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + arg_cpu_type = cpu_type_from_string(optarg); + if (arg_cpu_type < 0) + return log_error_errno(arg_cpu_type, "Unknown argument to --cpu=: %s", optarg); } else @@ -810,18 +836,9 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_ORDER: - if (streq(optarg, "path")) - arg_order = ORDER_PATH; - else if (streq(optarg, "tasks")) - arg_order = ORDER_TASKS; - else if (streq(optarg, "cpu")) - arg_order = ORDER_CPU; - else if (streq(optarg, "memory")) - arg_order = ORDER_MEMORY; - else if (streq(optarg, "io")) - arg_order = ORDER_IO; - else - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + arg_order = order_from_string(optarg); + if (arg_order < 0) + return log_error_errno(arg_order, "Invalid argument to --order=: %s", optarg); break; @@ -959,7 +976,7 @@ static int loop(const char *root) { break; case '%': - arg_cpu_type = arg_cpu_type == CPU_TIME ? CPU_PERCENT : CPU_TIME; + arg_cpu_type = arg_cpu_type == CPU_TIME ? CPU_PERCENTAGE : CPU_TIME; break; case 'k': diff --git a/src/core/main.c b/src/core/main.c index 4fc870d6c0..0f363d5c8f 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -255,6 +255,22 @@ static int console_setup(void) { return 0; } +static int parse_timeout(const char *value, usec_t *ret) { + int r = 0; + + assert(value); + assert(ret); + + if (streq(value, "default")) + *ret = USEC_INFINITY; + else if (streq(value, "off")) + *ret = 0; + else + r = parse_sec(value, ret); + + return r; +} + static int parse_proc_cmdline_item(const char *key, const char *value, void *data) { int r; @@ -456,16 +472,10 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat if (proc_cmdline_value_missing(key, value)) return 0; - if (streq(value, "default")) - arg_runtime_watchdog = USEC_INFINITY; - else if (streq(value, "off")) - arg_runtime_watchdog = 0; - else { - r = parse_sec(value, &arg_runtime_watchdog); - if (r < 0) { - log_warning_errno(r, "Failed to parse systemd.watchdog_sec= argument '%s', ignoring: %m", value); - return 0; - } + r = parse_timeout(value, &arg_runtime_watchdog); + if (r < 0) { + log_warning_errno(r, "Failed to parse systemd.watchdog_sec= argument '%s', ignoring: %m", value); + return 0; } arg_kexec_watchdog = arg_reboot_watchdog = arg_runtime_watchdog; @@ -475,16 +485,10 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat if (proc_cmdline_value_missing(key, value)) return 0; - if (streq(value, "default")) - arg_pretimeout_watchdog = USEC_INFINITY; - else if (streq(value, "off")) - arg_pretimeout_watchdog = 0; - else { - r = parse_sec(value, &arg_pretimeout_watchdog); - if (r < 0) { - log_warning_errno(r, "Failed to parse systemd.watchdog_pre_sec= argument '%s', ignoring: %m", value); - return 0; - } + r = parse_timeout(value, &arg_pretimeout_watchdog); + if (r < 0) { + log_warning_errno(r, "Failed to parse systemd.watchdog_pre_sec= argument '%s', ignoring: %m", value); + return 0; } } else if (proc_cmdline_key_streq(key, "systemd.watchdog_pretimeout_governor")) { diff --git a/src/detect-virt/detect-virt.c b/src/detect-virt/detect-virt.c index 3513f0b3b1..d28e302480 100644 --- a/src/detect-virt/detect-virt.c +++ b/src/detect-virt/detect-virt.c @@ -109,16 +109,14 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_LIST: - DUMP_STRING_TABLE(virtualization, Virtualization, _VIRTUALIZATION_MAX); - return 0; + return DUMP_STRING_TABLE(virtualization, Virtualization, _VIRTUALIZATION_MAX); case ARG_CVM: arg_mode = ONLY_CVM; return 1; case ARG_LIST_CVM: - DUMP_STRING_TABLE(confidential_virtualization, ConfidentialVirtualization, _CONFIDENTIAL_VIRTUALIZATION_MAX); - return 0; + return DUMP_STRING_TABLE(confidential_virtualization, ConfidentialVirtualization, _CONFIDENTIAL_VIRTUALIZATION_MAX); case '?': return -EINVAL; diff --git a/src/home/homectl.c b/src/home/homectl.c index 6c83765766..a73d94744a 100644 --- a/src/home/homectl.c +++ b/src/home/homectl.c @@ -56,6 +56,7 @@ #include "rlimit-util.h" #include "runtime-scope.h" #include "stat-util.h" +#include "string-table.h" #include "string-util.h" #include "strv.h" #include "terminal-util.h" @@ -69,6 +70,14 @@ #include "userdb.h" #include "verbs.h" +typedef enum { + EXPORT_FORMAT_FULL, /* export the full record */ + EXPORT_FORMAT_STRIPPED, /* strip "state" + "binding", but leave signature in place */ + EXPORT_FORMAT_MINIMAL, /* also strip signature */ + _EXPORT_FORMAT_MAX, + _EXPORT_FORMAT_INVALID = -EINVAL, +} ExportFormat; + static PagerFlags arg_pager_flags = 0; static bool arg_legend = true; static bool arg_ask_password = true; @@ -97,11 +106,7 @@ static bool arg_recovery_key = false; static sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF; static bool arg_and_resize = false; static bool arg_and_change_password = false; -static enum { - EXPORT_FORMAT_FULL, /* export the full record */ - EXPORT_FORMAT_STRIPPED, /* strip "state" + "binding", but leave signature in place */ - EXPORT_FORMAT_MINIMAL, /* also strip signature */ -} arg_export_format = EXPORT_FORMAT_FULL; +static ExportFormat arg_export_format = EXPORT_FORMAT_FULL; static uint64_t arg_capability_bounding_set = UINT64_MAX; static uint64_t arg_capability_ambient_set = UINT64_MAX; static char *arg_blob_dir = NULL; @@ -131,6 +136,14 @@ STATIC_DESTRUCTOR_REGISTER(arg_key_name, freep); static const BusLocator *bus_mgr; +static const char *export_format_table[_EXPORT_FORMAT_MAX] = { + [EXPORT_FORMAT_FULL] = "full", + [EXPORT_FORMAT_STRIPPED] = "stripped", + [EXPORT_FORMAT_MINIMAL] = "minimal", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP(export_format, ExportFormat); + static bool identity_properties_specified(void) { return arg_identity || @@ -4732,18 +4745,12 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_EXPORT_FORMAT: - if (streq(optarg, "full")) - arg_export_format = EXPORT_FORMAT_FULL; - else if (streq(optarg, "stripped")) - arg_export_format = EXPORT_FORMAT_STRIPPED; - else if (streq(optarg, "minimal")) - arg_export_format = EXPORT_FORMAT_MINIMAL; - else if (streq(optarg, "help")) { - puts("full\n" - "stripped\n" - "minimal"); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(export_format, ExportFormat, _EXPORT_FORMAT_MAX); + + arg_export_format = export_format_from_string(optarg); + if (arg_export_format < 0) + return log_error_errno(arg_export_format, "Invalid export format: %s", optarg); break; diff --git a/src/import/export.c b/src/import/export.c index b3edc1a787..d891ca1816 100644 --- a/src/import/export.c +++ b/src/import/export.c @@ -249,17 +249,8 @@ static int parse_argv(int argc, char *argv[]) { return version(); case ARG_FORMAT: - if (streq(optarg, "uncompressed")) - arg_compress = IMPORT_COMPRESS_UNCOMPRESSED; - else if (streq(optarg, "xz")) - arg_compress = IMPORT_COMPRESS_XZ; - else if (streq(optarg, "gzip")) - arg_compress = IMPORT_COMPRESS_GZIP; - else if (streq(optarg, "bzip2")) - arg_compress = IMPORT_COMPRESS_BZIP2; - else if (streq(optarg, "zstd")) - arg_compress = IMPORT_COMPRESS_ZSTD; - else + arg_compress = import_compress_type_from_string(optarg); + if (arg_compress < 0 || arg_compress == IMPORT_COMPRESS_UNKNOWN) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown format: %s", optarg); break; diff --git a/src/import/importctl.c b/src/import/importctl.c index e5f004e157..94140469c4 100644 --- a/src/import/importctl.c +++ b/src/import/importctl.c @@ -1127,10 +1127,8 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_VERIFY: - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(import_verify, ImportVerify, _IMPORT_VERIFY_MAX); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(import_verify, ImportVerify, _IMPORT_VERIFY_MAX); r = import_verify_from_string(optarg); if (r < 0) diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 93c8d0dde6..8c5fd2aed2 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -476,10 +476,8 @@ static int parse_argv(int argc, char *argv[]) { break; case 'o': - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX); arg_output = output_mode_from_string(optarg); if (arg_output < 0) diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 2c3394cc2c..c86f694c2b 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -1600,10 +1600,8 @@ static int parse_argv(int argc, char *argv[]) { break; case 'o': - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX); arg_output = output_mode_from_string(optarg); if (arg_output < 0) diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index c64b8b5bba..487a50813e 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -2295,10 +2295,8 @@ static int parse_argv(int argc, char *argv[]) { break; case 'o': - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX); r = output_mode_from_string(optarg); if (r < 0) @@ -2354,10 +2352,8 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_VERIFY: - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(import_verify, ImportVerify, _IMPORT_VERIFY_MAX); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(import_verify, ImportVerify, _IMPORT_VERIFY_MAX); r = import_verify_from_string(optarg); if (r < 0) diff --git a/src/nspawn/nspawn-settings.c b/src/nspawn/nspawn-settings.c index e4f4f5ebf1..c058ab28f7 100644 --- a/src/nspawn/nspawn-settings.c +++ b/src/nspawn/nspawn-settings.c @@ -914,6 +914,16 @@ static const char *const timezone_mode_table[_TIMEZONE_MODE_MAX] = { DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(timezone_mode, TimezoneMode, TIMEZONE_AUTO); +static const char *const console_mode_table[_CONSOLE_MODE_MAX] = { + [CONSOLE_AUTOPIPE] = "autopipe", + [CONSOLE_INTERACTIVE] = "interactive", + [CONSOLE_READ_ONLY] = "read-only", + [CONSOLE_PASSIVE] = "passive", + [CONSOLE_PIPE] = "pipe", +}; + +DEFINE_STRING_TABLE_LOOKUP(console_mode, ConsoleMode); + DEFINE_CONFIG_PARSE_ENUM(config_parse_userns_ownership, user_namespace_ownership, UserNamespaceOwnership); static const char *const user_namespace_ownership_table[_USER_NAMESPACE_OWNERSHIP_MAX] = { diff --git a/src/nspawn/nspawn-settings.h b/src/nspawn/nspawn-settings.h index 84631e6558..5b36c2ad47 100644 --- a/src/nspawn/nspawn-settings.h +++ b/src/nspawn/nspawn-settings.h @@ -82,6 +82,7 @@ typedef enum TimezoneMode { } TimezoneMode; typedef enum ConsoleMode { + CONSOLE_AUTOPIPE, CONSOLE_INTERACTIVE, CONSOLE_READ_ONLY, CONSOLE_PASSIVE, @@ -282,6 +283,9 @@ ResolvConfMode resolv_conf_mode_from_string(const char *s) _pure_; const char* timezone_mode_to_string(TimezoneMode a) _const_; TimezoneMode timezone_mode_from_string(const char *s) _pure_; +const char* console_mode_to_string(ConsoleMode m) _const_; +ConsoleMode console_mode_from_string(const char *s) _pure_; + const char* user_namespace_ownership_to_string(UserNamespaceOwnership a) _const_; UserNamespaceOwnership user_namespace_ownership_from_string(const char *s) _pure_; diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 88f03243d7..afe7ebd500 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -286,42 +286,6 @@ STATIC_DESTRUCTOR_REGISTER(arg_settings_filename, freep); STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep); STATIC_DESTRUCTOR_REGISTER(arg_background, freep); -static int handle_arg_console(const char *arg) { - if (streq(arg, "help")) { - puts("autopipe\n" - "interactive\n" - "passive\n" - "pipe\n" - "read-only"); - return 0; - } - - if (streq(arg, "interactive")) - arg_console_mode = CONSOLE_INTERACTIVE; - else if (streq(arg, "read-only")) - arg_console_mode = CONSOLE_READ_ONLY; - else if (streq(arg, "passive")) - arg_console_mode = CONSOLE_PASSIVE; - else if (streq(arg, "pipe")) { - if (isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO)) - log_full(arg_quiet ? LOG_DEBUG : LOG_NOTICE, - "Console mode 'pipe' selected, but standard input/output are connected to an interactive TTY. " - "Most likely you want to use 'interactive' console mode for proper interactivity and shell job control. " - "Proceeding anyway."); - - arg_console_mode = CONSOLE_PIPE; - } else if (streq(arg, "autopipe")) { - if (isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO)) - arg_console_mode = CONSOLE_INTERACTIVE; - else - arg_console_mode = CONSOLE_PIPE; - } else - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown console mode: %s", optarg); - - arg_settings_mask |= SETTING_CONSOLE_MODE; - return 1; -} - static int help(void) { _cleanup_free_ char *link = NULL; int r; @@ -1133,10 +1097,9 @@ static int parse_argv(int argc, char *argv[]) { if (!optarg) arg_volatile_mode = VOLATILE_YES; - else if (streq(optarg, "help")) { - DUMP_STRING_TABLE(volatile_mode, VolatileMode, _VOLATILE_MODE_MAX); - return 0; - } else { + else if (streq(optarg, "help")) + return DUMP_STRING_TABLE(volatile_mode, VolatileMode, _VOLATILE_MODE_MAX); + else { VolatileMode m; m = volatile_mode_from_string(optarg); @@ -1238,10 +1201,8 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_PRIVATE_USERS_OWNERSHIP: - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(user_namespace_ownership, UserNamespaceOwnership, _USER_NAMESPACE_OWNERSHIP_MAX); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(user_namespace_ownership, UserNamespaceOwnership, _USER_NAMESPACE_OWNERSHIP_MAX); arg_userns_ownership = user_namespace_ownership_from_string(optarg); if (arg_userns_ownership < 0) @@ -1251,10 +1212,8 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_KILL_SIGNAL: - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(signal, int, _NSIG); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(signal, int, _NSIG); arg_kill_signal = signal_from_string(optarg); if (arg_kill_signal < 0) @@ -1413,10 +1372,8 @@ static int parse_argv(int argc, char *argv[]) { _cleanup_free_ char *name = NULL; int rl; - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(rlimit, int, _RLIMIT_MAX); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(rlimit, int, _RLIMIT_MAX); eq = strchr(optarg, '='); if (!eq) @@ -1467,10 +1424,8 @@ static int parse_argv(int argc, char *argv[]) { } case ARG_RESOLV_CONF: - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(resolv_conf_mode, ResolvConfMode, _RESOLV_CONF_MODE_MAX); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(resolv_conf_mode, ResolvConfMode, _RESOLV_CONF_MODE_MAX); arg_resolv_conf = resolv_conf_mode_from_string(optarg); if (arg_resolv_conf < 0) @@ -1481,10 +1436,8 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_TIMEZONE: - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(timezone_mode, TimezoneMode, _TIMEZONE_MODE_MAX); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(timezone_mode, TimezoneMode, _TIMEZONE_MODE_MAX); arg_timezone = timezone_mode_from_string(optarg); if (arg_timezone < 0) @@ -1495,16 +1448,21 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_CONSOLE: - r = handle_arg_console(optarg); - if (r <= 0) - return r; + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(console_mode, ConsoleMode, _CONSOLE_MODE_MAX); + + arg_console_mode = console_mode_from_string(optarg); + if (arg_console_mode < 0) + return log_error_errno(arg_console_mode, "Unknown console mode: %s", optarg); + + arg_settings_mask |= SETTING_CONSOLE_MODE; + break; case 'P': case ARG_PIPE: - r = handle_arg_console("pipe"); - if (r <= 0) - return r; + arg_console_mode = CONSOLE_PIPE; + arg_settings_mask |= SETTING_CONSOLE_MODE; break; case ARG_NO_PAGER: @@ -1738,6 +1696,12 @@ static int verify_arguments(void) { if (r < 0) return r; + if (arg_console_mode == CONSOLE_PIPE && isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO)) + log_full(arg_quiet ? LOG_DEBUG : LOG_NOTICE, + "Console mode 'pipe' selected, but standard input/output are connected to an interactive TTY. " + "Most likely you want to use 'interactive' console mode for proper interactivity and shell job control. " + "Proceeding anyway."); + return 0; } @@ -5983,6 +5947,13 @@ static int run(int argc, char *argv[]) { arg_console_mode = isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO) ? CONSOLE_INTERACTIVE : CONSOLE_READ_ONLY; + if (arg_console_mode == CONSOLE_AUTOPIPE) { + if (isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO)) + arg_console_mode = CONSOLE_INTERACTIVE; + else + arg_console_mode = CONSOLE_PIPE; + } + if (arg_console_mode == CONSOLE_PIPE) /* if we pass STDERR on to the container, don't add our own logs into it too */ arg_quiet = true; diff --git a/src/shared/parse-argument.c b/src/shared/parse-argument.c index 107e3cb8ab..58b914f241 100644 --- a/src/shared/parse-argument.c +++ b/src/shared/parse-argument.c @@ -110,10 +110,8 @@ int parse_signal_argument(const char *s, int *ret) { assert(s); assert(ret); - if (streq(s, "help")) { - DUMP_STRING_TABLE(signal, int, _NSIG); - return 0; - } + if (streq(s, "help")) + return DUMP_STRING_TABLE(signal, int, _NSIG); if (streq(s, "list")) { _cleanup_(table_unrefp) Table *table = NULL; diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c index c88c104296..88278fc688 100644 --- a/src/sysext/sysext.c +++ b/src/sysext/sysext.c @@ -2581,8 +2581,7 @@ static int parse_argv(int argc, char *argv[]) { if (arg_legend) puts("Known mutability modes:"); - DUMP_STRING_TABLE(mutable_mode, MutableMode, _MUTABLE_MAX); - return 0; + return DUMP_STRING_TABLE(mutable_mode, MutableMode, _MUTABLE_MAX); } r = parse_mutable_mode(optarg); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 2eaf62a410..01b5517d14 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -810,10 +810,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) { break; case 'o': - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX); arg_output = output_mode_from_string(optarg); if (arg_output < 0) @@ -899,10 +897,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) { break; case ARG_PRESET_MODE: - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(unit_file_preset_mode, UnitFilePresetMode, _UNIT_FILE_PRESET_MODE_MAX); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(unit_file_preset_mode, UnitFilePresetMode, _UNIT_FILE_PRESET_MODE_MAX); arg_preset_mode = unit_file_preset_mode_from_string(optarg); if (arg_preset_mode < 0) @@ -964,10 +960,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) { break; case ARG_TIMESTAMP_STYLE: - if (streq(optarg, "help")) { - DUMP_STRING_TABLE(timestamp_style, TimestampStyle, _TIMESTAMP_STYLE_MAX); - return 0; - } + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(timestamp_style, TimestampStyle, _TIMESTAMP_STYLE_MAX); arg_timestamp_style = timestamp_style_from_string(optarg); if (arg_timestamp_style < 0) diff --git a/src/userdb/userdbctl.c b/src/userdb/userdbctl.c index 9959869e7a..4fbf8f671c 100644 --- a/src/userdb/userdbctl.c +++ b/src/userdb/userdbctl.c @@ -26,6 +26,7 @@ #include "pretty-print.h" #include "recurse-dir.h" #include "socket-util.h" +#include "string-table.h" #include "string-util.h" #include "strv.h" #include "uid-classification.h" @@ -37,14 +38,16 @@ #include "verbs.h" #include "virt.h" -static enum { +typedef enum { OUTPUT_CLASSIC, OUTPUT_TABLE, OUTPUT_FRIENDLY, OUTPUT_JSON, + _OUTPUT_MAX, _OUTPUT_INVALID = -EINVAL, -} arg_output = _OUTPUT_INVALID; +} Output; +static Output arg_output = _OUTPUT_INVALID; static PagerFlags arg_pager_flags = 0; static bool arg_legend = true; static char** arg_services = NULL; @@ -61,6 +64,15 @@ static sd_json_variant *arg_from_file = NULL; STATIC_DESTRUCTOR_REGISTER(arg_services, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_from_file, sd_json_variant_unrefp); +static const char *output_table[_OUTPUT_MAX] = { + [OUTPUT_CLASSIC] = "classic", + [OUTPUT_TABLE] = "table", + [OUTPUT_FRIENDLY] = "friendly", + [OUTPUT_JSON] = "json", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP(output, Output); + static const char *user_disposition_to_color(UserDisposition d) { assert(d >= 0); assert(d < _USER_DISPOSITION_MAX); @@ -1652,24 +1664,12 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_OUTPUT: - if (isempty(optarg)) - arg_output = _OUTPUT_INVALID; - else if (streq(optarg, "classic")) - arg_output = OUTPUT_CLASSIC; - else if (streq(optarg, "friendly")) - arg_output = OUTPUT_FRIENDLY; - else if (streq(optarg, "json")) - arg_output = OUTPUT_JSON; - else if (streq(optarg, "table")) - arg_output = OUTPUT_TABLE; - else if (streq(optarg, "help")) { - puts("classic\n" - "friendly\n" - "json\n" - "table"); - return 0; - } else - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid --output= mode: %s", optarg); + if (streq(optarg, "help")) + return DUMP_STRING_TABLE(output, Output, _OUTPUT_MAX); + + arg_output = output_from_string(optarg); + if (arg_output < 0) + return log_error_errno(arg_output, "Invalid --output= mode: %s", optarg); arg_json_format_flags = arg_output == OUTPUT_JSON ? SD_JSON_FORMAT_PRETTY|SD_JSON_FORMAT_COLOR_AUTO : SD_JSON_FORMAT_OFF; break; diff --git a/src/vpick/vpick-tool.c b/src/vpick/vpick-tool.c index c58bcb9d3c..2ed0762de2 100644 --- a/src/vpick/vpick-tool.c +++ b/src/vpick/vpick-tool.c @@ -13,16 +13,12 @@ #include "path-util.h" #include "pretty-print.h" #include "stat-util.h" +#include "string-table.h" #include "string-util.h" #include "strv.h" #include "vpick.h" -static char *arg_filter_basename = NULL; -static char *arg_filter_version = NULL; -static Architecture arg_filter_architecture = _ARCHITECTURE_INVALID; -static char *arg_filter_suffix = NULL; -static uint32_t arg_filter_type_mask = 0; -static enum { +typedef enum { PRINT_PATH, PRINT_FILENAME, PRINT_VERSION, @@ -30,14 +26,34 @@ static enum { PRINT_ARCHITECTURE, PRINT_TRIES, PRINT_ALL, + _PRINT_MAX, _PRINT_INVALID = -EINVAL, -} arg_print = _PRINT_INVALID; +} Print; + +static char *arg_filter_basename = NULL; +static char *arg_filter_version = NULL; +static Architecture arg_filter_architecture = _ARCHITECTURE_INVALID; +static char *arg_filter_suffix = NULL; +static uint32_t arg_filter_type_mask = 0; +static Print arg_print = _PRINT_INVALID; static PickFlags arg_flags = PICK_ARCHITECTURE|PICK_TRIES; STATIC_DESTRUCTOR_REGISTER(arg_filter_basename, freep); STATIC_DESTRUCTOR_REGISTER(arg_filter_version, freep); STATIC_DESTRUCTOR_REGISTER(arg_filter_suffix, freep); +static const char *print_table[_PRINT_MAX] = { + [PRINT_PATH] = "path", + [PRINT_FILENAME] = "filename", + [PRINT_VERSION] = "version", + [PRINT_TYPE] = "type", + [PRINT_ARCHITECTURE] = "architecture", + [PRINT_TRIES] = "tries", + [PRINT_ALL] = "all", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(print, Print); + static int help(void) { _cleanup_free_ char *link = NULL; int r; @@ -173,22 +189,12 @@ static int parse_argv(int argc, char *argv[]) { break; case 'p': - if (streq(optarg, "path")) - arg_print = PRINT_PATH; - else if (streq(optarg, "filename")) - arg_print = PRINT_FILENAME; - else if (streq(optarg, "version")) - arg_print = PRINT_VERSION; - else if (streq(optarg, "type")) - arg_print = PRINT_TYPE; - else if (STR_IN_SET(optarg, "arch", "architecture")) + if (streq(optarg, "arch")) /* accept abbreviation too */ arg_print = PRINT_ARCHITECTURE; - else if (streq(optarg, "tries")) - arg_print = PRINT_TRIES; - else if (streq(optarg, "all")) - arg_print = PRINT_ALL; else - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown --print= argument: %s", optarg); + arg_print = print_from_string(optarg); + if (arg_print < 0) + return log_error_errno(arg_print, "Unknown --print= argument: %s", optarg); break;