From: Zbigniew Jędrzejewski-Szmek Date: Fri, 27 Feb 2026 19:20:53 +0000 (+0100) Subject: notify: use the new option parser X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0e4459eb19eca4dee60513dad6ae49d4f36e83c1;p=thirdparty%2Fsystemd.git notify: use the new option parser Cosmetic adjustments to one help string. --- diff --git a/src/notify/notify.c b/src/notify/notify.c index 6a39147f99e..cdca928f90a 100644 --- a/src/notify/notify.c +++ b/src/notify/notify.c @@ -1,6 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include #include #include #include @@ -16,10 +15,12 @@ #include "exit-status.h" #include "fd-util.h" #include "fdset.h" +#include "format-table.h" #include "format-util.h" #include "log.h" #include "main-func.h" #include "notify-recv.h" +#include "options.h" #include "parse-util.h" #include "pidref.h" #include "pretty-print.h" @@ -57,40 +58,28 @@ STATIC_DESTRUCTOR_REGISTER(arg_fdname, freep); static int help(void) { _cleanup_free_ char *link = NULL; + _cleanup_(table_unrefp) Table *options = NULL; int r; r = terminal_urlify_man("systemd-notify", "1", &link); if (r < 0) return log_oom(); - printf("%s [OPTIONS...] [VARIABLE=VALUE...]\n" - "%s [OPTIONS...] --exec [VARIABLE=VALUE...] ; -- CMDLINE...\n" - "%s [OPTIONS...] --fork -- CMDLINE...\n" - "\n%sNotify the init system about service status updates.%s\n\n" - " -h --help Show this help\n" - " --version Show package version\n" - " --ready Inform the service manager about service start-up/reload\n" - " completion\n" - " --reloading Inform the service manager about configuration reloading\n" - " --stopping Inform the service manager about service shutdown\n" - " --pid[=PID] Set main PID of daemon\n" - " --uid=USER Set user to send from\n" - " --status=TEXT Set status text\n" - " --booted Check if the system was booted up with systemd\n" - " --no-block Do not wait until operation finished\n" - " --exec Execute command line separated by ';' once done\n" - " --fd=FD Pass specified file descriptor with along with message\n" - " --fdname=NAME Name to assign to passed file descriptor(s)\n" - " --fork Receive notifications from child rather than sending them\n" - " -q --quiet Do not show PID of child when forking\n" - "\nSee the %s for details.\n", - program_invocation_short_name, - program_invocation_short_name, + r = option_parser_get_help_table(&options); + if (r < 0) + return r; + + printf("%1$s [OPTIONS...] [VARIABLE=VALUE...]\n" + "%1$s [OPTIONS...] --exec [VARIABLE=VALUE...] ; -- CMDLINE...\n" + "%1$s [OPTIONS...] --fork -- CMDLINE...\n" + "\n%2$sNotify the init system about service status updates.%3$s\n\n", program_invocation_short_name, ansi_highlight(), - ansi_normal(), - link); + ansi_normal()); + + table_print(options, stdout); + printf("\nSee the %s for details.\n", link); return 0; } @@ -161,123 +150,87 @@ from_self: return pidref_set_self(ret); } -static int parse_argv(int argc, char *argv[]) { - - enum { - ARG_READY = 0x100, - ARG_RELOADING, - ARG_STOPPING, - ARG_VERSION, - ARG_PID, - ARG_STATUS, - ARG_BOOTED, - ARG_UID, - ARG_NO_BLOCK, - ARG_EXEC, - ARG_FD, - ARG_FDNAME, - ARG_FORK, - }; - - static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "ready", no_argument, NULL, ARG_READY }, - { "reloading", no_argument, NULL, ARG_RELOADING }, - { "stopping", no_argument, NULL, ARG_STOPPING }, - { "pid", optional_argument, NULL, ARG_PID }, - { "status", required_argument, NULL, ARG_STATUS }, - { "booted", no_argument, NULL, ARG_BOOTED }, - { "uid", required_argument, NULL, ARG_UID }, - { "no-block", no_argument, NULL, ARG_NO_BLOCK }, - { "exec", no_argument, NULL, ARG_EXEC }, - { "fd", required_argument, NULL, ARG_FD }, - { "fdname", required_argument, NULL, ARG_FDNAME }, - { "fork", no_argument, NULL, ARG_FORK }, - { "quiet", no_argument, NULL, 'q' }, - {} - }; - +static int parse_argv(int argc, char *argv[], char ***ret_args) { _cleanup_fdset_free_ FDSet *passed = NULL; bool do_exec = false; - int c, r; + int r; assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "hq", options, NULL)) >= 0) { + OptionParser state = {}; + const char *arg; + FOREACH_OPTION(&state, c, argc, argv, &arg, /* on_error= */ return c) switch (c) { - case 'h': + OPTION_COMMON_HELP: return help(); - case ARG_VERSION: + OPTION_COMMON_VERSION: return version(); - case ARG_READY: + OPTION_LONG("ready", NULL, + "Inform the service manager about service start-up/reload completion"): arg_ready = true; break; - case ARG_RELOADING: + OPTION_LONG("reloading", NULL, + "Inform the service manager about configuration reloading"): arg_reloading = true; break; - case ARG_STOPPING: + OPTION_LONG("stopping", NULL, + "Inform the service manager about service shutdown"): arg_stopping = true; break; - case ARG_PID: + OPTION_FULL(OPTION_OPTIONAL_ARG, /* sc= */ 0, "pid", "PID", + "Set main PID of daemon"): pidref_done(&arg_pid); - if (isempty(optarg) || streq(optarg, "auto")) + if (isempty(arg) || streq(arg, "auto")) r = pidref_parent_if_applicable(&arg_pid); - else if (streq(optarg, "parent")) + else if (streq(arg, "parent")) r = pidref_set_parent(&arg_pid); - else if (streq(optarg, "self")) + else if (streq(arg, "self")) r = pidref_set_self(&arg_pid); else - r = pidref_set_pidstr(&arg_pid, optarg); + r = pidref_set_pidstr(&arg_pid, arg); if (r < 0) - return log_error_errno(r, "Failed to refer to --pid='%s': %m", optarg); - + return log_error_errno(r, "Failed to refer to --pid='%s': %m", arg); break; - case ARG_STATUS: - arg_status = optarg; + OPTION_LONG("uid", "USER", "Set user to send from"): + r = get_user_creds(&arg, &arg_uid, &arg_gid, NULL, NULL, 0); + if (r == -ESRCH) /* If the user doesn't exist, then accept it anyway as numeric */ + r = parse_uid(arg, &arg_uid); + if (r < 0) + return log_error_errno(r, "Can't resolve user %s: %m", arg); break; - case ARG_BOOTED: - arg_action = ACTION_BOOTED; + OPTION_LONG("status", "TEXT", "Set status text"): + arg_status = arg; break; - case ARG_UID: { - const char *u = optarg; - - r = get_user_creds(&u, &arg_uid, &arg_gid, NULL, NULL, 0); - if (r == -ESRCH) /* If the user doesn't exist, then accept it anyway as numeric */ - r = parse_uid(u, &arg_uid); - if (r < 0) - return log_error_errno(r, "Can't resolve user %s: %m", optarg); - + OPTION_LONG("booted", NULL, "Check if the system was booted up with systemd"): + arg_action = ACTION_BOOTED; break; - } - case ARG_NO_BLOCK: + OPTION_LONG("no-block", NULL, "Do not wait until operation finished"): arg_no_block = true; break; - case ARG_EXEC: + OPTION_LONG("exec", NULL, "Execute command line separated by ';' once done"): do_exec = true; break; - case ARG_FD: { + OPTION_LONG("fd", "FD", "Pass specified file descriptor along with the message"): { _cleanup_close_ int owned_fd = -EBADF; - int fdnr; - fdnr = parse_fd(optarg); + int fdnr = parse_fd(arg); if (fdnr < 0) - return log_error_errno(fdnr, "Failed to parse file descriptor: %s", optarg); + return log_error_errno(fdnr, "Failed to parse file descriptor: %s", arg); if (!passed) { /* Take possession of all passed fds */ @@ -310,33 +263,28 @@ static int parse_argv(int argc, char *argv[]) { break; } - case ARG_FDNAME: - if (!fdname_is_valid(optarg)) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "File descriptor name invalid: %s", optarg); + OPTION_LONG("fdname", "NAME", "Name to assign to passed file descriptors"): + if (!fdname_is_valid(arg)) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "File descriptor name invalid: %s", arg); - if (free_and_strdup(&arg_fdname, optarg) < 0) + if (free_and_strdup(&arg_fdname, arg) < 0) return log_oom(); break; - case ARG_FORK: + OPTION_LONG("fork", NULL, "Receive notifications from child rather than sending them"): arg_action = ACTION_FORK; break; - case 'q': + OPTION('q', "quiet", NULL, "Do not show PID of child when forking"): arg_quiet = true; break; - - case '?': - return -EINVAL; - - default: - assert_not_reached(); } - } bool have_env = arg_ready || arg_stopping || arg_reloading || arg_status || pidref_is_set(&arg_pid) || !fdset_isempty(arg_fds); + char **args = option_parser_get_args(&state, argc, argv); + switch (arg_action) { case ACTION_NOTIFY: { @@ -348,22 +296,22 @@ static int parse_argv(int argc, char *argv[]) { if (do_exec) { int i; - for (i = optind; i < argc; i++) - if (streq(argv[i], ";")) + for (i = 0; args[i]; i++) + if (streq(args[i], ";")) break; - if (i >= argc) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "If --exec is used argument list must contain ';' separator, refusing."); - if (i+1 == argc) + if (!args[i]) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "If --exec is used, argument list must contain ';' separator, refusing."); + if (!args[i + 1]) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Empty command line specified after ';' separator, refusing."); - arg_exec = strv_copy_n(argv + i + 1, argc - i - 1); + arg_exec = strv_copy(args + i + 1); if (!arg_exec) return log_oom(); - n_arg_env = i - optind; + n_arg_env = i; } else - n_arg_env = argc - optind; + n_arg_env = strv_length(args); have_env = have_env || n_arg_env > 0; if (!have_env) { @@ -376,7 +324,7 @@ static int parse_argv(int argc, char *argv[]) { } if (n_arg_env > 0) { - arg_env = strv_copy_n(argv + optind, n_arg_env); + arg_env = strv_copy_n(args, n_arg_env); if (!arg_env) return log_oom(); } @@ -388,13 +336,13 @@ static int parse_argv(int argc, char *argv[]) { } case ACTION_BOOTED: - if (argc > optind) + if (!strv_isempty(args)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--booted takes no parameters, refusing."); break; case ACTION_FORK: - if (optind >= argc) + if (strv_isempty(args)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--fork requires a command to be specified, refusing."); break; @@ -404,7 +352,10 @@ static int parse_argv(int argc, char *argv[]) { } if (have_env && arg_action != ACTION_NOTIFY) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--ready, --reloading, --stopping, --pid=, --status=, --fd= may not be combined with --fork or --booted, refusing."); + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "--ready, --reloading, --stopping, --pid=, --status=, --fd= may not be combined with --fork or --booted, refusing."); + + *ret_args = args; return 1; } @@ -577,16 +528,17 @@ static int run(int argc, char* argv[]) { _cleanup_strv_free_ char **final_env = NULL; const char *our_env[10]; size_t i = 0; + char **args; int r; log_setup(); - r = parse_argv(argc, argv); + r = parse_argv(argc, argv, &args); if (r <= 0) return r; if (arg_action == ACTION_FORK) - return action_fork(argv + optind); + return action_fork(args); if (arg_action == ACTION_BOOTED) { r = sd_booted();