From: Zbigniew Jędrzejewski-Szmek Date: Tue, 14 Apr 2026 13:08:25 +0000 (+0200) Subject: cgtop: convert to the new option parser X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=09a62b706b376d48a5dfdaedda457f21146a21cb;p=thirdparty%2Fsystemd.git cgtop: convert to the new option parser A few --help strings are changed to the common option variants. The optional args for --unit, --user-unit, --xattr, --cgroup-id are shown in synopsis. A define is defined for the default of --depth to make things clearer. Co-developed-by: Claude Opus 4.6 --- diff --git a/src/cgtop/cgtop.c b/src/cgtop/cgtop.c index 24a4be64ecc..b8194de3d3e 100644 --- a/src/cgtop/cgtop.c +++ b/src/cgtop/cgtop.c @@ -1,6 +1,5 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include #include #include @@ -10,9 +9,11 @@ #include "cgroup-util.h" #include "fd-util.h" #include "fileio.h" +#include "format-table.h" #include "hashmap.h" #include "log.h" #include "main-func.h" +#include "options.h" #include "parse-argument.h" #include "parse-util.h" #include "path-util.h" @@ -72,13 +73,15 @@ typedef enum { _CPU_INVALID = -EINVAL, } CPUType; -static unsigned arg_depth = 3; +#define DEFAULT_MAXIMUM_DEPTH 3 + +static unsigned arg_depth = DEFAULT_MAXIMUM_DEPTH; static unsigned arg_iterations = UINT_MAX; static bool arg_batch = false; static bool arg_raw = false; static usec_t arg_delay = 1*USEC_PER_SEC; -static char* arg_machine = NULL; -static char* arg_root = NULL; +static const char *arg_machine = NULL; +static const char *arg_root = NULL; static bool arg_recursive = true; static bool arg_recursive_unset = false; static PidsCount arg_count = COUNT_PIDS; @@ -687,194 +690,151 @@ static void display(Hashmap *a) { static int help(void) { _cleanup_free_ char *link = NULL; + _cleanup_(table_unrefp) Table *options = NULL; int r; r = terminal_urlify_man("systemd-cgtop", "1", &link); if (r < 0) return log_oom(); + r = option_parser_get_help_table(&options); + if (r < 0) + return r; + printf("%s [OPTIONS...] [CGROUP]\n\n" - "Show top control groups by their resource usage.\n\n" - " -h --help Show this help\n" - " --version Show package version\n" - - " --order=path|tasks|cpu|memory|io\n" - " Order by specified property\n" - " -p Same as --order=path, order by path\n" - " -t Same as --order=tasks, order by number of\n" - " tasks/processes\n" - " -c Same as --order=cpu, order by CPU load\n" - " -m Same as --order=memory, order by memory load\n" - " -i Same as --order=io, order by IO load\n" - " -r --raw Provide raw (not human-readable) numbers\n" - " --cpu[=percentage]\n" - " Show CPU usage as percentage (default)\n" - " --cpu=time Show CPU usage as time\n" - " -P Count userspace processes instead of tasks (excl. kernel)\n" - " -k Count all processes instead of tasks (incl. kernel)\n" - " --recursive=BOOL Sum up process count recursively\n" - " -d --delay=DELAY Delay between updates\n" - " -n --iterations=N Run for N iterations before exiting\n" - " -1 Shortcut for --iterations=1\n" - " -b --batch Run in batch mode, accepting no input\n" - " --depth=DEPTH Maximum traversal depth (default: %u)\n" - " -M --machine= Show container\n" - "\nSee the %s for details.\n", + "%sShow top control groups by their resource usage.%s\n\n", program_invocation_short_name, - arg_depth, - link); + ansi_highlight(), + ansi_normal()); + + r = table_print_or_warn(options); + if (r < 0) + return r; + printf("\nSee the %s for details.\n", link); return 0; } static int parse_argv(int argc, char *argv[]) { - enum { - ARG_VERSION = 0x100, - ARG_DEPTH, - ARG_CPU_TYPE, - ARG_ORDER, - ARG_RECURSIVE, - }; - - static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "delay", required_argument, NULL, 'd' }, - { "iterations", required_argument, NULL, 'n' }, - { "batch", no_argument, NULL, 'b' }, - { "raw", no_argument, NULL, 'r' }, - { "depth", required_argument, NULL, ARG_DEPTH }, - { "cpu", optional_argument, NULL, ARG_CPU_TYPE }, - { "order", required_argument, NULL, ARG_ORDER }, - { "recursive", required_argument, NULL, ARG_RECURSIVE }, - { "machine", required_argument, NULL, 'M' }, - {} - }; - - int c, r; - assert(argc >= 1); assert(argv); - while ((c = getopt_long(argc, argv, "hptcmin:brd:kPM:1", options, NULL)) >= 0) + OptionParser state = { argc, argv }; + const char *arg; + int r; + FOREACH_OPTION(&state, c, &arg, /* on_error= */ return c) switch (c) { - case 'h': + OPTION_COMMON_HELP: return help(); - case ARG_VERSION: + OPTION_COMMON_VERSION: return version(); - case ARG_ORDER: - arg_order = order_from_string(optarg); + OPTION_LONG("order", "PROPERTY", + "Order by specified property (path, tasks, cpu, memory, io)"): + arg_order = order_from_string(arg); if (arg_order < 0) return log_error_errno(arg_order, "Invalid argument to --order=: %s", - optarg); + arg); break; - case 'p': + OPTION_SHORT('p', NULL, "Same as --order=path, order by path"): arg_order = ORDER_PATH; break; - case 't': + OPTION_SHORT('t', NULL, "Same as --order=tasks, order by number of tasks/processes"): arg_order = ORDER_TASKS; break; - case 'c': + OPTION_SHORT('c', NULL, "Same as --order=cpu, order by CPU load"): arg_order = ORDER_CPU; break; - case 'm': + OPTION_SHORT('m', NULL, "Same as --order=memory, order by memory load"): arg_order = ORDER_MEMORY; break; - case 'i': + OPTION_SHORT('i', NULL, "Same as --order=io, order by IO load"): arg_order = ORDER_IO; break; - case 'r': + OPTION('r', "raw", NULL, "Provide raw (not human-readable) numbers"): arg_raw = true; break; - case ARG_CPU_TYPE: - if (optarg) { - arg_cpu_type = cpu_type_from_string(optarg); + OPTION_LONG_FLAGS(OPTION_OPTIONAL_ARG, "cpu", "percentage|time", + "Show CPU usage as percentage (default) or time"): + if (arg) { + arg_cpu_type = cpu_type_from_string(arg); if (arg_cpu_type < 0) return log_error_errno(arg_cpu_type, "Unknown argument to --cpu=: %s", - optarg); + arg); } else arg_cpu_type = CPU_TIME; - break; - case 'P': + OPTION_SHORT('P', NULL, "Count userspace processes instead of tasks (excl. kernel)"): arg_count = COUNT_USERSPACE_PROCESSES; break; - case 'k': + OPTION_SHORT('k', NULL, "Count all processes instead of tasks (incl. kernel)"): arg_count = COUNT_ALL_PROCESSES; break; - case ARG_RECURSIVE: - r = parse_boolean_argument("--recursive=", optarg, &arg_recursive); + OPTION_LONG("recursive", "BOOL", "Sum up process count recursively"): + r = parse_boolean_argument("--recursive=", arg, &arg_recursive); if (r < 0) return r; arg_recursive_unset = !r; break; - case 'd': - r = parse_sec(optarg, &arg_delay); + OPTION('d', "delay", "DELAY", "Delay between updates"): + r = parse_sec(arg, &arg_delay); if (r < 0) - return log_error_errno(r, "Failed to parse delay parameter '%s': %m", optarg); + return log_error_errno(r, "Failed to parse delay parameter '%s': %m", arg); if (arg_delay <= 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid delay parameter '%s'", - optarg); - + arg); break; - case 'n': - r = safe_atou(optarg, &arg_iterations); + OPTION('n', "iterations", "N", "Run for N iterations before exiting"): + r = safe_atou(arg, &arg_iterations); if (r < 0) - return log_error_errno(r, "Failed to parse iterations parameter '%s': %m", optarg); - + return log_error_errno(r, "Failed to parse iterations parameter '%s': %m", arg); break; - case '1': + OPTION_SHORT('1', NULL, "Shortcut for --iterations=1"): arg_iterations = 1; break; - case 'b': + OPTION('b', "batch", NULL, "Run in batch mode, accepting no input"): arg_batch = true; break; - case ARG_DEPTH: - r = safe_atou(optarg, &arg_depth); + OPTION_LONG("depth", "DEPTH", + "Maximum traversal depth (default: "STRINGIFY(DEFAULT_MAXIMUM_DEPTH)")"): + r = safe_atou(arg, &arg_depth); if (r < 0) - return log_error_errno(r, "Failed to parse depth parameter '%s': %m", optarg); - + return log_error_errno(r, "Failed to parse depth parameter '%s': %m", arg); break; - case 'M': - arg_machine = optarg; + OPTION_COMMON_MACHINE: + arg_machine = arg; break; - - case '?': - return -EINVAL; - - default: - assert_not_reached(); } - if (optind == argc - 1) - arg_root = argv[optind]; - else if (optind < argc) + size_t n_args = option_parser_get_n_args(&state); + if (n_args > 1) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Too many arguments."); + if (n_args == 1) + arg_root = option_parser_get_args(&state)[0]; return 1; }