Convert remaining udev progs to option macros (#41856)
This commit is contained in:
@@ -31,7 +31,6 @@
|
||||
#include "process-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "tpm2-pcr.h"
|
||||
#include "tpm2-util.h"
|
||||
|
||||
@@ -579,14 +578,12 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
}
|
||||
|
||||
char **args = option_parser_get_args(&opts);
|
||||
if (option_parser_get_n_args(&opts) > 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Too many arguments, refusing.");
|
||||
|
||||
if (strv_length(args) > 1)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Too many arguments, refusing.");
|
||||
|
||||
if (args[0])
|
||||
r = parse_path_argument(args[0], false, &arg_node);
|
||||
const char *arg = option_parser_get_arg(&opts, 0);
|
||||
if (arg)
|
||||
r = parse_path_argument(arg, false, &arg_node);
|
||||
else if (!wipe_requested())
|
||||
r = determine_default_node();
|
||||
else
|
||||
|
||||
+1
-2
@@ -181,8 +181,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
"%s expects exactly one argument (the mount point).",
|
||||
program_invocation_short_name);
|
||||
|
||||
arg_target = option_parser_get_args(&opts)[0];
|
||||
|
||||
arg_target = option_parser_get_arg(&opts, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1420,7 +1420,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
* the old container user functionality. To maintain backwards compatibility
|
||||
* with the space-separated form (--user NAME), if the next opts.arg does not look
|
||||
* like an option, interpret it as a user name. */
|
||||
const char *t = option_parser_next_arg(&opts);
|
||||
const char *t = option_parser_peek_next_arg(&opts);
|
||||
if (t && t[0] != '-') {
|
||||
opts.arg = option_parser_consume_next_arg(&opts);
|
||||
log_warning("--user NAME is deprecated, use --uid=NAME instead.");
|
||||
|
||||
+1
-1
@@ -188,7 +188,7 @@ static int help_sudo_mode(void) {
|
||||
* sudo's short switches, hence please do not introduce new short switches unless they have a roughly
|
||||
* equivalent purpose on sudo. Use long options for everything private to run0. */
|
||||
|
||||
r = option_parser_get_help_table_full("run0", /* group= */ NULL, &opts_table);
|
||||
r = option_parser_get_help_table_ns("run0", &opts_table);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
+10
-2
@@ -344,7 +344,7 @@ int option_parse(
|
||||
return r;
|
||||
}
|
||||
|
||||
char* option_parser_next_arg(const OptionParser *state) {
|
||||
char* option_parser_peek_next_arg(const OptionParser *state) {
|
||||
/* Peek at the next argument, whatever it is (option or position arg).
|
||||
* May return NULL. */
|
||||
|
||||
@@ -360,7 +360,7 @@ char* option_parser_consume_next_arg(OptionParser *state) {
|
||||
* so we won't try to interpret it as an option.
|
||||
* May return NULL. */
|
||||
|
||||
char *t = option_parser_next_arg(state);
|
||||
char *t = option_parser_peek_next_arg(state);
|
||||
if (t)
|
||||
shift_arg(state->argv, state->positional_offset++, state->optind++);
|
||||
return t;
|
||||
@@ -388,6 +388,14 @@ size_t option_parser_get_n_args(const OptionParser *state) {
|
||||
return state->argc - state->positional_offset;
|
||||
}
|
||||
|
||||
char* option_parser_get_arg(const OptionParser *state, size_t i) {
|
||||
assert(state->optind > 0);
|
||||
assert(state->state == OPTION_PARSER_DONE);
|
||||
assert(state->positional_offset <= state->argc);
|
||||
|
||||
return (size_t) (state->argc - state->positional_offset) > i ? state->argv[state->positional_offset + i] : NULL;
|
||||
}
|
||||
|
||||
char* option_get_synopsis(const Option *opt, const char *joiner, bool show_metavar) {
|
||||
assert(opt);
|
||||
assert(!(opt->flags & (OPTION_NAMESPACE_MARKER |
|
||||
|
||||
+14
-3
@@ -150,10 +150,13 @@ typedef struct Option {
|
||||
"(file, provider:PROVIDER)")
|
||||
|
||||
/* A form used in udev code for compatibility. -V is accepted but not documented. */
|
||||
#define OPTION_COMMON_VERSION_WITH_HIDDEN_V \
|
||||
OPTION_COMMON_VERSION: {} \
|
||||
#define OPTION_COMMON_VERSION_WITH_HIDDEN_V \
|
||||
OPTION_COMMON_VERSION: {} \
|
||||
OPTION_SHORT('V', NULL, /* help= */ NULL)
|
||||
|
||||
#define OPTION_COMMON_RESOLVE_NAMES \
|
||||
OPTION('N', "resolve-names", "MODE", \
|
||||
"When to resolve users and groups (early, late, or never)")
|
||||
|
||||
/* This is magically mapped to the beginning and end of the section */
|
||||
extern const Option __start_SYSTEMD_OPTIONS[];
|
||||
@@ -221,11 +224,17 @@ int option_parse(
|
||||
break; \
|
||||
} else
|
||||
|
||||
char* option_parser_next_arg(const OptionParser *state);
|
||||
/* Those helpers are used *during* option parsing and allow looking at or taking the next item in
|
||||
* the argv array, either an option or a positional parameter. */
|
||||
char* option_parser_peek_next_arg(const OptionParser *state);
|
||||
char* option_parser_consume_next_arg(OptionParser *state);
|
||||
|
||||
/* Those helpers are used *after* option parsing and return the positional arguments (and unparsed
|
||||
* options in case option parsing was stopped early, e.g. via "--"). */
|
||||
char** option_parser_get_args(const OptionParser *state);
|
||||
size_t option_parser_get_n_args(const OptionParser *state);
|
||||
char* option_parser_get_arg(const OptionParser *state, size_t i);
|
||||
|
||||
char* option_get_synopsis(const Option *opt, const char *joiner, bool show_metavar);
|
||||
|
||||
int _option_parser_get_help_table_full(
|
||||
@@ -236,6 +245,8 @@ int _option_parser_get_help_table_full(
|
||||
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)
|
||||
#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) \
|
||||
option_parser_get_help_table_full(/* namespace= */ NULL, group, ret)
|
||||
#define option_parser_get_help_table(ret) \
|
||||
|
||||
+12
-7
@@ -58,7 +58,12 @@ static void test_option_parse_one(
|
||||
ASSERT_TRUE(strv_equal(args, remaining));
|
||||
ASSERT_STREQ(argv[0], saved_argv0);
|
||||
|
||||
ASSERT_EQ(option_parser_get_n_args(&opts), strv_length(remaining));
|
||||
size_t l = strv_length(remaining);
|
||||
ASSERT_EQ(option_parser_get_n_args(&opts), l);
|
||||
ASSERT_STREQ(option_parser_get_arg(&opts, 0), l > 0 ? remaining[0] : NULL);
|
||||
ASSERT_STREQ(option_parser_get_arg(&opts, 1), l > 1 ? remaining[1] : NULL);
|
||||
ASSERT_STREQ(option_parser_get_arg(&opts, 2), l > 2 ? remaining[2] : NULL);
|
||||
ASSERT_STREQ(option_parser_get_arg(&opts, 3), l > 3 ? remaining[3] : NULL);
|
||||
}
|
||||
|
||||
static void test_option_invalid_one(
|
||||
@@ -1331,7 +1336,7 @@ TEST(option_optional_arg_consume) {
|
||||
|
||||
/* --user without arg: next arg is positional (doesn't start with -).
|
||||
* The option parser returns NULL for the arg. The caller would then
|
||||
* use option_parser_next_arg/consume_next_arg to grab it. */
|
||||
* use option_parser_peek_next_arg/consume_next_arg to grab it. */
|
||||
{
|
||||
char **argv = STRV_MAKE("arg0", "--user", "someuser", "pos1");
|
||||
int argc = strv_length(argv);
|
||||
@@ -1341,7 +1346,7 @@ TEST(option_optional_arg_consume) {
|
||||
ASSERT_OK_POSITIVE(option_parse(options, options + 3, &opts));
|
||||
ASSERT_STREQ(opts.opt->long_code, "user");
|
||||
ASSERT_NULL(opts.arg);
|
||||
ASSERT_STREQ(option_parser_next_arg(&opts), "someuser");
|
||||
ASSERT_STREQ(option_parser_peek_next_arg(&opts), "someuser");
|
||||
ASSERT_STREQ(option_parser_consume_next_arg(&opts), "someuser");
|
||||
|
||||
ASSERT_EQ(option_parse(options, options + 3, &opts), 0);
|
||||
@@ -1361,7 +1366,7 @@ TEST(option_optional_arg_consume) {
|
||||
ASSERT_OK_POSITIVE(option_parse(options, options + 3, &opts));
|
||||
ASSERT_STREQ(opts.opt->long_code, "user");
|
||||
ASSERT_NULL(opts.arg);
|
||||
ASSERT_NULL(option_parser_next_arg(&opts));
|
||||
ASSERT_NULL(option_parser_peek_next_arg(&opts));
|
||||
ASSERT_NULL(option_parser_consume_next_arg(&opts));
|
||||
|
||||
ASSERT_EQ(option_parse(options, options + 3, &opts), 0);
|
||||
@@ -1381,12 +1386,12 @@ TEST(option_optional_arg_consume) {
|
||||
ASSERT_OK_POSITIVE(option_parse(options, options + 3, &opts));
|
||||
ASSERT_STREQ(opts.opt->long_code, "user");
|
||||
ASSERT_NULL(opts.arg);
|
||||
ASSERT_STREQ(option_parser_next_arg(&opts), "-u");
|
||||
ASSERT_STREQ(option_parser_peek_next_arg(&opts), "-u");
|
||||
|
||||
ASSERT_OK_POSITIVE(option_parse(options, options + 3, &opts));
|
||||
ASSERT_STREQ(opts.opt->long_code, "uid");
|
||||
ASSERT_STREQ(opts.arg, "nobody");
|
||||
ASSERT_NULL(option_parser_next_arg(&opts));
|
||||
ASSERT_NULL(option_parser_peek_next_arg(&opts));
|
||||
ASSERT_NULL(option_parser_consume_next_arg(&opts));
|
||||
|
||||
ASSERT_EQ(option_parse(options, options + 3, &opts), 0);
|
||||
@@ -1413,7 +1418,7 @@ TEST(option_optional_arg_consume) {
|
||||
const char *arg = opts.arg;
|
||||
|
||||
if (!arg) {
|
||||
const char *t = option_parser_next_arg(&opts);
|
||||
const char *t = option_parser_peek_next_arg(&opts);
|
||||
if (t && t[0] != '-')
|
||||
arg = option_parser_consume_next_arg(&opts);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <linux/loop.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -26,6 +25,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "initrd-util.h"
|
||||
#include "gpt.h"
|
||||
#include "options.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
@@ -506,13 +506,6 @@ static int builtin_blkid(UdevEvent *event, int argc, char *argv[]) {
|
||||
int64_t offset = 0;
|
||||
int r;
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "offset", required_argument, NULL, 'o' },
|
||||
{ "hint", required_argument, NULL, 'H' },
|
||||
{ "noraid", no_argument, NULL, 'R' },
|
||||
{}
|
||||
};
|
||||
|
||||
r = dlopen_libblkid(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return log_device_debug_errno(dev, r, "blkid not available: %m");
|
||||
@@ -522,32 +515,32 @@ static int builtin_blkid(UdevEvent *event, int argc, char *argv[]) {
|
||||
if (!pr)
|
||||
return log_device_debug_errno(dev, errno_or_else(ENOMEM), "Failed to create blkid prober: %m");
|
||||
|
||||
for (;;) {
|
||||
int option;
|
||||
OptionParser opts = { argc, argv, .namespace = "udev-builtin-blkid" };
|
||||
|
||||
option = getopt_long(argc, argv, "o:H:R", options, NULL);
|
||||
if (option == -1)
|
||||
break;
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
|
||||
switch (option) {
|
||||
case 'H':
|
||||
OPTION_NAMESPACE("udev-builtin-blkid"): {}
|
||||
|
||||
OPTION('H', "hint", "HINT", NULL):
|
||||
errno = 0;
|
||||
r = sym_blkid_probe_set_hint(pr, optarg, 0);
|
||||
r = sym_blkid_probe_set_hint(pr, opts.arg, 0);
|
||||
if (r < 0)
|
||||
return log_device_error_errno(dev, errno_or_else(ENOMEM), "Failed to use '%s' probing hint: %m", optarg);
|
||||
return log_device_error_errno(dev, errno_or_else(ENOMEM), "Failed to use '%s' probing hint: %m", opts.arg);
|
||||
break;
|
||||
case 'o':
|
||||
r = safe_atoi64(optarg, &offset);
|
||||
|
||||
OPTION('o', "offset", "OFFSET", NULL):
|
||||
r = safe_atoi64(opts.arg, &offset);
|
||||
if (r < 0)
|
||||
return log_device_error_errno(dev, r, "Failed to parse '%s' as an integer: %m", optarg);
|
||||
return log_device_error_errno(dev, r, "Failed to parse '%s' as an integer: %m", opts.arg);
|
||||
if (offset < 0)
|
||||
return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Invalid offset %"PRIi64".", offset);
|
||||
break;
|
||||
case 'R':
|
||||
|
||||
OPTION('R', "noraid", NULL, NULL):
|
||||
noraid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_device_get_devname(dev, &devnode);
|
||||
if (r < 0)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "sd-hwdb.h"
|
||||
@@ -9,6 +8,7 @@
|
||||
#include "alloc-util.h"
|
||||
#include "device-util.h"
|
||||
#include "hwdb-util.h"
|
||||
#include "options.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-util.h"
|
||||
#include "udev-builtin.h"
|
||||
@@ -128,13 +128,6 @@ next:
|
||||
}
|
||||
|
||||
static int builtin_hwdb(UdevEvent *event, int argc, char *argv[]) {
|
||||
static const struct option options[] = {
|
||||
{ "filter", required_argument, NULL, 'f' },
|
||||
{ "device", required_argument, NULL, 'd' },
|
||||
{ "subsystem", required_argument, NULL, 's' },
|
||||
{ "lookup-prefix", required_argument, NULL, 'p' },
|
||||
{}
|
||||
};
|
||||
const char *filter = NULL, *device = NULL, *subsystem = NULL, *prefix = NULL;
|
||||
_cleanup_(sd_device_unrefp) sd_device *srcdev = NULL;
|
||||
sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
|
||||
@@ -143,35 +136,34 @@ static int builtin_hwdb(UdevEvent *event, int argc, char *argv[]) {
|
||||
if (!hwdb)
|
||||
return -EINVAL;
|
||||
|
||||
for (;;) {
|
||||
int option;
|
||||
OptionParser opts = { argc, argv, .namespace = "udev-builtin-hwdb" };
|
||||
|
||||
option = getopt_long(argc, argv, "f:d:s:p:", options, NULL);
|
||||
if (option == -1)
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
|
||||
OPTION_NAMESPACE("udev-builtin-hwdb"): {}
|
||||
|
||||
OPTION('f', "filter", "FILTER", NULL):
|
||||
filter = opts.arg;
|
||||
break;
|
||||
|
||||
switch (option) {
|
||||
case 'f':
|
||||
filter = optarg;
|
||||
OPTION('d', "device", "DEVICE", NULL):
|
||||
device = opts.arg;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
device = optarg;
|
||||
OPTION('s', "subsystem", "SUBSYSTEM", NULL):
|
||||
subsystem = opts.arg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
subsystem = optarg;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
prefix = optarg;
|
||||
OPTION('p', "lookup-prefix", "PREFIX", NULL):
|
||||
prefix = opts.arg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* query a specific key given as argument */
|
||||
if (argv[optind]) {
|
||||
r = udev_builtin_hwdb_lookup(event, prefix, argv[optind], filter);
|
||||
char *modalias = option_parser_get_arg(&opts, 0);
|
||||
if (modalias) {
|
||||
r = udev_builtin_hwdb_lookup(event, prefix, modalias, filter);
|
||||
if (r < 0)
|
||||
return log_device_debug_errno(dev, r, "Failed to look up hwdb: %m");
|
||||
if (r == 0)
|
||||
|
||||
+58
-76
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "conf-parser.h"
|
||||
@@ -8,10 +7,12 @@
|
||||
#include "daemon-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "format-table.h"
|
||||
#include "hashmap.h"
|
||||
#include "help-util.h"
|
||||
#include "limits-util.h"
|
||||
#include "options.h"
|
||||
#include "parse-util.h"
|
||||
#include "pretty-print.h"
|
||||
#include "proc-cmdline.h"
|
||||
#include "serialize.h"
|
||||
#include "signal-util.h"
|
||||
@@ -149,110 +150,91 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
|
||||
}
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = terminal_urlify_man("systemd-udevd.service", "8", &link);
|
||||
r = option_parser_get_help_table_ns("udevd", &options);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
return r;
|
||||
|
||||
printf("%s [OPTIONS...]\n\n"
|
||||
"Rule-based manager for device events and files.\n\n"
|
||||
" -h --help Print this message\n"
|
||||
" -V --version Print version of the program\n"
|
||||
" -d --daemon Detach and run in the background\n"
|
||||
" -D --debug Enable debug output\n"
|
||||
" -c --children-max=INT Set maximum number of workers\n"
|
||||
" -e --exec-delay=SECONDS Seconds to wait before executing RUN=\n"
|
||||
" -t --event-timeout=SECONDS Seconds to wait before terminating an event\n"
|
||||
" -N --resolve-names=early|late|never\n"
|
||||
" When to resolve users and groups\n"
|
||||
"\nSee the %s for details.\n",
|
||||
program_invocation_short_name,
|
||||
link);
|
||||
help_cmdline("[OPTIONS...]");
|
||||
help_abstract("Rule-based manager for device events and files.");
|
||||
|
||||
help_section("Options:");
|
||||
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_man_page_reference("systemd-udevd.service", "8");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[], UdevConfig *config) {
|
||||
enum {
|
||||
ARG_TIMEOUT_SIGNAL,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "daemon", no_argument, NULL, 'd' },
|
||||
{ "debug", no_argument, NULL, 'D' },
|
||||
{ "children-max", required_argument, NULL, 'c' },
|
||||
{ "exec-delay", required_argument, NULL, 'e' },
|
||||
{ "event-timeout", required_argument, NULL, 't' },
|
||||
{ "resolve-names", required_argument, NULL, 'N' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "timeout-signal", required_argument, NULL, ARG_TIMEOUT_SIGNAL },
|
||||
{}
|
||||
};
|
||||
|
||||
int c, r;
|
||||
int r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
assert(config);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "c:de:Dt:N:hV", options, NULL)) >= 0) {
|
||||
OptionParser opts = { argc, argv, OPTION_PARSER_NORMAL, "udevd" };
|
||||
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
|
||||
case 'd':
|
||||
OPTION_NAMESPACE("udevd"): {}
|
||||
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
OPTION('V', "version", NULL, "Show package version"):
|
||||
printf("%s\n", GIT_VERSION);
|
||||
return 0;
|
||||
|
||||
OPTION('d', "daemon", NULL, "Detach and run in the background"):
|
||||
arg_daemonize = true;
|
||||
break;
|
||||
case 'c':
|
||||
r = safe_atou(optarg, &config->children_max);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse --children-max= value '%s', ignoring: %m", optarg);
|
||||
break;
|
||||
case 'e':
|
||||
r = parse_sec(optarg, &config->exec_delay_usec);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse --exec-delay= value '%s', ignoring: %m", optarg);
|
||||
break;
|
||||
case ARG_TIMEOUT_SIGNAL:
|
||||
r = signal_from_string(optarg);
|
||||
if (r <= 0)
|
||||
log_warning_errno(r, "Failed to parse --timeout-signal= value '%s', ignoring: %m", optarg);
|
||||
else
|
||||
config->timeout_signal = r;
|
||||
|
||||
break;
|
||||
case 't':
|
||||
r = parse_sec(optarg, &config->timeout_usec);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse --event-timeout= value '%s', ignoring: %m", optarg);
|
||||
break;
|
||||
case 'D':
|
||||
OPTION('D', "debug", NULL, "Enable debug output"):
|
||||
arg_debug = true;
|
||||
config->log_level = LOG_DEBUG;
|
||||
break;
|
||||
case 'N': {
|
||||
ResolveNameTiming t;
|
||||
|
||||
t = resolve_name_timing_from_string(optarg);
|
||||
OPTION('c', "children-max", "INT", "Set maximum number of workers"):
|
||||
r = safe_atou(opts.arg, &config->children_max);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse --children-max= value '%s', ignoring: %m", opts.arg);
|
||||
break;
|
||||
|
||||
OPTION('e', "exec-delay", "SECONDS", "Seconds to wait before executing RUN="):
|
||||
r = parse_sec(opts.arg, &config->exec_delay_usec);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse --exec-delay= value '%s', ignoring: %m", opts.arg);
|
||||
break;
|
||||
|
||||
OPTION('t', "event-timeout", "SECONDS", "Seconds to wait before terminating an event"):
|
||||
r = parse_sec(opts.arg, &config->timeout_usec);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse --event-timeout= value '%s', ignoring: %m", opts.arg);
|
||||
break;
|
||||
|
||||
OPTION_COMMON_RESOLVE_NAMES: {
|
||||
ResolveNameTiming t = resolve_name_timing_from_string(opts.arg);
|
||||
if (t < 0)
|
||||
log_warning("Invalid --resolve-names= value '%s', ignoring.", optarg);
|
||||
log_warning("Invalid --resolve-names= value '%s', ignoring.", opts.arg);
|
||||
else
|
||||
config->resolve_name_timing = t;
|
||||
break;
|
||||
}
|
||||
case 'h':
|
||||
return help();
|
||||
case 'V':
|
||||
printf("%s\n", GIT_VERSION);
|
||||
return 0;
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
default:
|
||||
assert_not_reached();
|
||||
|
||||
OPTION_LONG("timeout-signal", "SIGNAL", "Signal used when terminating an event"):
|
||||
r = signal_from_string(opts.arg);
|
||||
if (r <= 0)
|
||||
log_warning_errno(r, "Failed to parse --timeout-signal= value '%s', ignoring: %m", opts.arg);
|
||||
else
|
||||
config->timeout_signal = r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
+40
-48
@@ -1,14 +1,14 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "conf-files.h"
|
||||
#include "format-table.h"
|
||||
#include "help-util.h"
|
||||
#include "log.h"
|
||||
#include "options.h"
|
||||
#include "parse-argument.h"
|
||||
#include "pretty-print.h"
|
||||
#include "static-destruct.h"
|
||||
#include "strv.h"
|
||||
#include "udevadm.h"
|
||||
#include "udevadm-util.h"
|
||||
|
||||
@@ -19,83 +19,75 @@ static bool arg_config = false;
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = terminal_urlify_man("udevadm", "8", &link);
|
||||
r = option_parser_get_help_table_ns("udevadm-cat", &options);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
return r;
|
||||
|
||||
printf("%s cat [OPTIONS] [FILE...]\n"
|
||||
"\n%sShow udev rules files.%s\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" -V --version Show package version\n"
|
||||
" --root=PATH Operate on an alternate filesystem root\n"
|
||||
" --tldr Skip comments and empty lines\n"
|
||||
" --config Show udev.conf rather than udev rules files\n"
|
||||
"\nSee the %s for details.\n",
|
||||
program_invocation_short_name,
|
||||
ansi_highlight(),
|
||||
ansi_normal(),
|
||||
link);
|
||||
help_cmdline("cat [OPTIONS...] [FILE...]");
|
||||
help_abstract("Show udev rules files.");
|
||||
help_section("Options:");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_man_page_reference("udevadm", "8");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_ROOT = 0x100,
|
||||
ARG_TLDR,
|
||||
ARG_CONFIG,
|
||||
};
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "root", required_argument, NULL, ARG_ROOT },
|
||||
{ "tldr", no_argument, NULL, ARG_TLDR },
|
||||
{ "config", no_argument, NULL, ARG_CONFIG },
|
||||
{}
|
||||
};
|
||||
|
||||
int r, c;
|
||||
static int parse_argv(int argc, char *argv[], char ***remaining_args) {
|
||||
int r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
assert(remaining_args);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "hVN:", options, NULL)) >= 0)
|
||||
OptionParser opts = { argc, argv, .namespace = "udevadm-cat" };
|
||||
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
case 'h':
|
||||
|
||||
OPTION_NAMESPACE("udevadm-cat"): {}
|
||||
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
case 'V':
|
||||
|
||||
OPTION_COMMON_VERSION_WITH_HIDDEN_V:
|
||||
return print_version();
|
||||
case ARG_ROOT:
|
||||
r = parse_path_argument(optarg, /* suppress_root= */ true, &arg_root);
|
||||
|
||||
OPTION_LONG("root", "PATH",
|
||||
"Operate on an alternate filesystem root"):
|
||||
r = parse_path_argument(opts.arg, /* suppress_root= */ true, &arg_root);
|
||||
if (r < 0)
|
||||
return r;
|
||||
break;
|
||||
case ARG_TLDR:
|
||||
|
||||
OPTION_LONG("tldr", NULL,
|
||||
"Skip comments and empty lines"):
|
||||
arg_cat_flags = CAT_TLDR;
|
||||
break;
|
||||
case ARG_CONFIG:
|
||||
|
||||
OPTION_LONG("config", NULL,
|
||||
"Show udev.conf rather than udev rules files"):
|
||||
arg_config = true;
|
||||
break;
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
if (arg_config && optind < argc)
|
||||
if (arg_config && option_parser_get_n_args(&opts) > 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Combination of --config and FILEs is not supported.");
|
||||
|
||||
*remaining_args = option_parser_get_args(&opts);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int verb_cat_main(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
char **args = NULL;
|
||||
int r;
|
||||
|
||||
r = parse_argv(argc, argv);
|
||||
r = parse_argv(argc, argv, &args);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@@ -107,7 +99,7 @@ int verb_cat_main(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
|
||||
CLEANUP_ARRAY(files, n_files, conf_file_free_array);
|
||||
|
||||
r = search_rules_files(strv_skip(argv, optind), arg_root, &files, &n_files);
|
||||
r = search_rules_files(args, arg_root, &files, &n_files);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
+56
-85
@@ -1,12 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "creds-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "format-table.h"
|
||||
#include "help-util.h"
|
||||
#include "log.h"
|
||||
#include "options.h"
|
||||
#include "parse-argument.h"
|
||||
#include "parse-util.h"
|
||||
#include "static-destruct.h"
|
||||
@@ -47,151 +48,121 @@ static bool arg_has_control_commands(void) {
|
||||
}
|
||||
|
||||
static int help(void) {
|
||||
printf("%s control OPTION\n\n"
|
||||
"Control the udev daemon.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" -V --version Show package version\n"
|
||||
" -e --exit Instruct the daemon to cleanup and exit\n"
|
||||
" -l --log-level=LEVEL Set the udev log level for the daemon\n"
|
||||
" -s --stop-exec-queue Do not execute events, queue only\n"
|
||||
" -S --start-exec-queue Execute events, flush queue\n"
|
||||
" -R --reload Reload rules and databases\n"
|
||||
" -p --property=KEY=VALUE Set a global property for all events\n"
|
||||
" -m --children-max=N Maximum number of children\n"
|
||||
" --ping Wait for udev to respond to a ping message\n"
|
||||
" --trace=BOOL Enable/disable trace logging\n"
|
||||
" --revert Revert previously set configurations\n"
|
||||
" -t --timeout=SECONDS Maximum time to block for a reply\n"
|
||||
" --load-credentials Load udev rules from credentials\n",
|
||||
program_invocation_short_name);
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = option_parser_get_help_table_ns("udevadm-control", &options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_cmdline("control OPTION");
|
||||
help_abstract("Control the udev daemon.");
|
||||
help_section("Options:");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_man_page_reference("udevadm", "8");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_PING = 0x100,
|
||||
ARG_TRACE,
|
||||
ARG_REVERT,
|
||||
ARG_LOAD_CREDENTIALS,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "exit", no_argument, NULL, 'e' },
|
||||
{ "log-level", required_argument, NULL, 'l' },
|
||||
{ "log-priority", required_argument, NULL, 'l' }, /* for backward compatibility */
|
||||
{ "stop-exec-queue", no_argument, NULL, 's' },
|
||||
{ "start-exec-queue", no_argument, NULL, 'S' },
|
||||
{ "reload", no_argument, NULL, 'R' },
|
||||
{ "reload-rules", no_argument, NULL, 'R' }, /* alias for -R */
|
||||
{ "property", required_argument, NULL, 'p' },
|
||||
{ "env", required_argument, NULL, 'p' }, /* alias for -p */
|
||||
{ "children-max", required_argument, NULL, 'm' },
|
||||
{ "ping", no_argument, NULL, ARG_PING },
|
||||
{ "trace", required_argument, NULL, ARG_TRACE },
|
||||
{ "revert", no_argument, NULL, ARG_REVERT },
|
||||
{ "timeout", required_argument, NULL, 't' },
|
||||
{ "load-credentials", no_argument, NULL, ARG_LOAD_CREDENTIALS },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{}
|
||||
};
|
||||
|
||||
int c, r;
|
||||
int r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "el:sSRp:m:t:Vh", options, NULL)) >= 0)
|
||||
OptionParser opts = { argc, argv, .namespace = "udevadm-control" };
|
||||
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
|
||||
case 'e':
|
||||
OPTION_NAMESPACE("udevadm-control"): {}
|
||||
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
OPTION('V', "version", NULL, "Show package version"):
|
||||
return print_version();
|
||||
|
||||
OPTION('e', "exit", NULL, "Instruct the daemon to cleanup and exit"):
|
||||
arg_exit = true;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
arg_log_level = log_level_from_string(optarg);
|
||||
OPTION_LONG("log-priority", "LEVEL", NULL): {} /* backward compat alias for --log-level */
|
||||
OPTION('l', "log-level", "LEVEL", "Set the udev log level for the daemon"):
|
||||
arg_log_level = log_level_from_string(opts.arg);
|
||||
if (arg_log_level < 0)
|
||||
return log_error_errno(arg_log_level, "Failed to parse log level '%s': %m", optarg);
|
||||
return log_error_errno(arg_log_level, "Failed to parse log level '%s': %m", opts.arg);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
OPTION('s', "stop-exec-queue", NULL, "Do not execute events, queue only"):
|
||||
arg_start_exec_queue = false;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
OPTION('S', "start-exec-queue", NULL, "Execute events, flush queue"):
|
||||
arg_start_exec_queue = true;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
OPTION_LONG("reload-rules", NULL, NULL): {} /* hidden alias for -R */
|
||||
OPTION('R', "reload", NULL, "Reload rules and databases"):
|
||||
arg_reload = true;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if (!strchr(optarg, '='))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "expect <KEY>=<value> instead of '%s'", optarg);
|
||||
OPTION_LONG("env", "KEY=VALUE", NULL): {} /* hidden alias for -p */
|
||||
OPTION('p', "property", "KEY=VALUE", "Set a global property for all events"):
|
||||
if (!strchr(opts.arg, '='))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "expect <KEY>=<value> instead of '%s'", opts.arg);
|
||||
|
||||
r = strv_extend(&arg_env, optarg);
|
||||
r = strv_extend(&arg_env, opts.arg);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extend environment: %m");
|
||||
|
||||
break;
|
||||
|
||||
case 'm': {
|
||||
OPTION('m', "children-max", "N", "Maximum number of children"): {
|
||||
unsigned i;
|
||||
r = safe_atou(optarg, &i);
|
||||
r = safe_atou(opts.arg, &i);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse maximum number of children '%s': %m", optarg);
|
||||
return log_error_errno(r, "Failed to parse maximum number of children '%s': %m", opts.arg);
|
||||
arg_max_children = i;
|
||||
break;
|
||||
}
|
||||
|
||||
case ARG_PING:
|
||||
OPTION_LONG("ping", NULL, "Wait for udev to respond to a ping message"):
|
||||
arg_ping = true;
|
||||
break;
|
||||
|
||||
case ARG_TRACE:
|
||||
r = parse_boolean_argument("--trace=", optarg, NULL);
|
||||
OPTION_LONG("trace", "BOOL", "Enable/disable trace logging"):
|
||||
r = parse_boolean_argument("--trace=", opts.arg, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
arg_trace = r;
|
||||
break;
|
||||
|
||||
case ARG_REVERT:
|
||||
OPTION_LONG("revert", NULL, "Revert previously set configurations"):
|
||||
arg_revert = true;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
r = parse_sec(optarg, &arg_timeout);
|
||||
OPTION('t', "timeout", "SECONDS", "Maximum time to block for a reply"):
|
||||
r = parse_sec(opts.arg, &arg_timeout);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse timeout value '%s': %m", optarg);
|
||||
return log_error_errno(r, "Failed to parse timeout value '%s': %m", opts.arg);
|
||||
break;
|
||||
|
||||
case ARG_LOAD_CREDENTIALS:
|
||||
OPTION_LONG("load-credentials", NULL, "Load udev rules from credentials"):
|
||||
arg_load_credentials = true;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
return print_version();
|
||||
|
||||
case 'h':
|
||||
return help();
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
if (!arg_has_control_commands() && !arg_load_credentials)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"No control command option is specified.");
|
||||
|
||||
if (optind < argc)
|
||||
if (option_parser_get_n_args(&opts) > 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Extraneous argument: %s", argv[optind]);
|
||||
"This subprogram takes no positional arguments.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
+47
-46
@@ -1,10 +1,12 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "format-table.h"
|
||||
#include "help-util.h"
|
||||
#include "hwdb-util.h"
|
||||
#include "log.h"
|
||||
#include "options.h"
|
||||
#include "udevadm.h"
|
||||
|
||||
static const char *arg_test = NULL;
|
||||
@@ -14,65 +16,64 @@ static bool arg_update = false;
|
||||
static bool arg_strict = false;
|
||||
|
||||
static int help(void) {
|
||||
printf("%s hwdb [OPTIONS]\n\n"
|
||||
" -h --help Print this message\n"
|
||||
" -V --version Print version of the program\n"
|
||||
" -u --update Update the hardware database\n"
|
||||
" -s --strict When updating, return non-zero exit value on any parsing error\n"
|
||||
" --usr Generate in " UDEVLIBEXECDIR " instead of /etc/udev\n"
|
||||
" -t --test=MODALIAS Query database and print result\n"
|
||||
" -r --root=PATH Alternative root path in the filesystem\n\n"
|
||||
"NOTE:\n"
|
||||
"The sub-command 'hwdb' is deprecated, and is left for backwards compatibility.\n"
|
||||
"Please use systemd-hwdb instead.\n",
|
||||
program_invocation_short_name);
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = option_parser_get_help_table_ns("udevadm-hwdb", &options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_cmdline("hwdb [OPTIONS]");
|
||||
help_abstract("Update or query the hardware database.");
|
||||
help_section("Options:");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
printf("\nNOTE:\n"
|
||||
"The sub-command 'hwdb' is deprecated, and is left for backwards compatibility.\n"
|
||||
"Please use systemd-hwdb instead.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_USR = 0x100,
|
||||
};
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "update", no_argument, NULL, 'u' },
|
||||
{ "usr", no_argument, NULL, ARG_USR },
|
||||
{ "strict", no_argument, NULL, 's' },
|
||||
{ "test", required_argument, NULL, 't' },
|
||||
{ "root", required_argument, NULL, 'r' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{}
|
||||
};
|
||||
OptionParser opts = { argc, argv, .namespace = "udevadm-hwdb" };
|
||||
|
||||
int c;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "ust:r:Vh", options, NULL)) >= 0)
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
case 'u':
|
||||
|
||||
OPTION_NAMESPACE("udevadm-hwdb"): {}
|
||||
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
OPTION('V', "version", NULL, "Show package version"):
|
||||
return print_version();
|
||||
|
||||
OPTION('u', "update", NULL, "Update the hardware database"):
|
||||
arg_update = true;
|
||||
break;
|
||||
case ARG_USR:
|
||||
arg_hwdb_bin_dir = UDEVLIBEXECDIR;
|
||||
break;
|
||||
case 's':
|
||||
|
||||
OPTION('s', "strict", NULL,
|
||||
"When updating, return non-zero exit value on any parsing error"):
|
||||
arg_strict = true;
|
||||
break;
|
||||
case 't':
|
||||
arg_test = optarg;
|
||||
|
||||
OPTION_LONG("usr", NULL,
|
||||
"Generate in " UDEVLIBEXECDIR " instead of /etc/udev"):
|
||||
arg_hwdb_bin_dir = UDEVLIBEXECDIR;
|
||||
break;
|
||||
case 'r':
|
||||
arg_root = optarg;
|
||||
|
||||
OPTION('t', "test", "MODALIAS", "Query database and print result"):
|
||||
arg_test = opts.arg;
|
||||
break;
|
||||
|
||||
OPTION('r', "root", "PATH", "Alternative root path in the filesystem"):
|
||||
arg_root = opts.arg;
|
||||
break;
|
||||
case 'V':
|
||||
return print_version();
|
||||
case 'h':
|
||||
return help();
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
+114
-180
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysmacros.h>
|
||||
@@ -20,7 +19,10 @@
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "format-table.h"
|
||||
#include "glyph-util.h"
|
||||
#include "help-util.h"
|
||||
#include "options.h"
|
||||
#include "pager.h"
|
||||
#include "parse-argument.h"
|
||||
#include "sort-util.h"
|
||||
@@ -800,51 +802,21 @@ static int query_device(QueryType query, sd_device* device) {
|
||||
}
|
||||
|
||||
static int help(void) {
|
||||
printf("%s info [OPTIONS] [DEVPATH|FILE]\n\n"
|
||||
"Query sysfs or the udev database.\n\n"
|
||||
" -h --help Print this message\n"
|
||||
" -V --version Print version of the program\n"
|
||||
" -q --query=TYPE Query device information:\n"
|
||||
" name Name of device node\n"
|
||||
" symlink Pointing to node\n"
|
||||
" path sysfs device path\n"
|
||||
" property The device properties\n"
|
||||
" all All values\n"
|
||||
" --property=NAME Show only properties by this name\n"
|
||||
" --value When showing properties, print only their values\n"
|
||||
" -p --path=SYSPATH sysfs device path used for query or attribute walk\n"
|
||||
" -n --name=NAME Node or symlink name used for query or attribute walk\n"
|
||||
" -r --root Prepend dev directory to path names\n"
|
||||
" -a --attribute-walk Print all key matches walking along the chain\n"
|
||||
" of parent devices\n"
|
||||
" -t --tree Show tree of devices\n"
|
||||
" -d --device-id-of-file=FILE Print major:minor of device containing this file\n"
|
||||
" -x --export Export key/value pairs\n"
|
||||
" -P --export-prefix Export the key name with a prefix\n"
|
||||
" -e --export-db Export the content of the udev database\n"
|
||||
" -c --cleanup-db Clean up the udev database\n"
|
||||
" -w --wait-for-initialization[=SECONDS]\n"
|
||||
" Wait for device to be initialized\n"
|
||||
" --no-pager Do not pipe output into a pager\n"
|
||||
" --json=pretty|short|off Generate JSON output\n"
|
||||
" --subsystem-match=SUBSYSTEM\n"
|
||||
" Query devices matching a subsystem\n"
|
||||
" --subsystem-nomatch=SUBSYSTEM\n"
|
||||
" Query devices not matching a subsystem\n"
|
||||
" --attr-match=FILE[=VALUE]\n"
|
||||
" Query devices that match an attribute\n"
|
||||
" --attr-nomatch=FILE[=VALUE]\n"
|
||||
" Query devices that do not match an attribute\n"
|
||||
" --property-match=KEY=VALUE\n"
|
||||
" Query devices with matching properties\n"
|
||||
" --tag-match=TAG Query devices with a matching tag\n"
|
||||
" --sysname-match=NAME Query devices with this /sys path\n"
|
||||
" --name-match=NAME Query devices with this /dev name\n"
|
||||
" --parent-match=NAME Query devices with this parent device\n"
|
||||
" --initialized-match Query devices that are already initialized\n"
|
||||
" --initialized-nomatch Query devices that are not initialized yet\n",
|
||||
program_invocation_short_name);
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = option_parser_get_help_table_ns("udevadm-info", &options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_cmdline("info [OPTIONS] [DEVPATH|FILE]");
|
||||
help_abstract("Query sysfs or the udev database.");
|
||||
help_section("Options:");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_man_page_reference("udevadm", "8");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1006,90 +978,64 @@ static int print_tree(sd_device* below) {
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_PROPERTY = 0x100,
|
||||
ARG_VALUE,
|
||||
ARG_NO_PAGER,
|
||||
ARG_JSON,
|
||||
ARG_SUBSYSTEM_MATCH,
|
||||
ARG_SUBSYSTEM_NOMATCH,
|
||||
ARG_ATTR_MATCH,
|
||||
ARG_ATTR_NOMATCH,
|
||||
ARG_PROPERTY_MATCH,
|
||||
ARG_TAG_MATCH,
|
||||
ARG_SYSNAME_MATCH,
|
||||
ARG_NAME_MATCH,
|
||||
ARG_PARENT_MATCH,
|
||||
ARG_INITIALIZED_MATCH,
|
||||
ARG_INITIALIZED_NOMATCH,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "attribute-walk", no_argument, NULL, 'a' },
|
||||
{ "tree", no_argument, NULL, 't' },
|
||||
{ "cleanup-db", no_argument, NULL, 'c' },
|
||||
{ "device-id-of-file", required_argument, NULL, 'd' },
|
||||
{ "export", no_argument, NULL, 'x' },
|
||||
{ "export-db", no_argument, NULL, 'e' },
|
||||
{ "export-prefix", required_argument, NULL, 'P' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "name", required_argument, NULL, 'n' },
|
||||
{ "path", required_argument, NULL, 'p' },
|
||||
{ "property", required_argument, NULL, ARG_PROPERTY },
|
||||
{ "query", required_argument, NULL, 'q' },
|
||||
{ "root", no_argument, NULL, 'r' },
|
||||
{ "value", no_argument, NULL, ARG_VALUE },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "wait-for-initialization", optional_argument, NULL, 'w' },
|
||||
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||
{ "json", required_argument, NULL, ARG_JSON },
|
||||
{ "subsystem-match", required_argument, NULL, ARG_SUBSYSTEM_MATCH },
|
||||
{ "subsystem-nomatch", required_argument, NULL, ARG_SUBSYSTEM_NOMATCH },
|
||||
{ "attr-match", required_argument, NULL, ARG_ATTR_MATCH },
|
||||
{ "attr-nomatch", required_argument, NULL, ARG_ATTR_NOMATCH },
|
||||
{ "property-match", required_argument, NULL, ARG_PROPERTY_MATCH },
|
||||
{ "tag-match", required_argument, NULL, ARG_TAG_MATCH },
|
||||
{ "sysname-match", required_argument, NULL, ARG_SYSNAME_MATCH },
|
||||
{ "name-match", required_argument, NULL, ARG_NAME_MATCH },
|
||||
{ "parent-match", required_argument, NULL, ARG_PARENT_MATCH },
|
||||
{ "initialized-match", no_argument, NULL, ARG_INITIALIZED_MATCH },
|
||||
{ "initialized-nomatch", no_argument, NULL, ARG_INITIALIZED_NOMATCH },
|
||||
{}
|
||||
};
|
||||
|
||||
int c, r;
|
||||
int r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "atced:n:p:q:rxP:w::Vh", options, NULL)) >= 0)
|
||||
OptionParser opts = { argc, argv, .namespace = "udevadm-info" };
|
||||
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
|
||||
case ARG_PROPERTY:
|
||||
OPTION_NAMESPACE("udevadm-info"): {}
|
||||
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
OPTION('V', "version", NULL, "Show package version"):
|
||||
return print_version();
|
||||
|
||||
OPTION('q', "query", "TYPE", "Query device information:"): {}
|
||||
OPTION_HELP_VERBATIM(" name", "- name of device node"): {}
|
||||
OPTION_HELP_VERBATIM(" symlink", "- pointing to node"): {}
|
||||
OPTION_HELP_VERBATIM(" path", "- sysfs device path"): {}
|
||||
OPTION_HELP_VERBATIM(" property", "- the device properties"): {}
|
||||
OPTION_HELP_VERBATIM(" all", "- all values"):
|
||||
arg_query = query_type_from_string(opts.arg);
|
||||
if (arg_query < 0) {
|
||||
if (streq(opts.arg, "env")) /* deprecated */
|
||||
arg_query = QUERY_PROPERTY;
|
||||
else
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown query type '%s'", opts.arg);
|
||||
}
|
||||
break;
|
||||
|
||||
OPTION_LONG("property", "NAME", "Show only properties by this name"):
|
||||
/* Make sure that if the empty property list was specified, we won't show any
|
||||
properties. */
|
||||
if (isempty(optarg) && !arg_properties) {
|
||||
if (isempty(opts.arg) && !arg_properties) {
|
||||
arg_properties = new0(char*, 1);
|
||||
if (!arg_properties)
|
||||
return log_oom();
|
||||
} else {
|
||||
r = strv_split_and_extend(&arg_properties, optarg, ",", true);
|
||||
r = strv_split_and_extend(&arg_properties, opts.arg, ",", true);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
}
|
||||
break;
|
||||
|
||||
case ARG_VALUE:
|
||||
OPTION_LONG("value", NULL,
|
||||
"When showing properties, print only their values"):
|
||||
arg_value = true;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
case 'p': {
|
||||
const char *prefix = c == 'n' ? "/dev/" : "/sys/";
|
||||
OPTION('p', "path", "SYSPATH", "sysfs device path used for query or attribute walk"): {} /* fall through */
|
||||
OPTION('n', "name", "NAME", "Node or symlink name used for query or attribute walk"): {
|
||||
const char *prefix = opts.opt->short_code == 'n' ? "/dev/" : "/sys/";
|
||||
char *path;
|
||||
|
||||
path = path_join(path_startswith(optarg, prefix) ? NULL : prefix, optarg);
|
||||
path = path_join(path_startswith(opts.arg, prefix) ? NULL : prefix, opts.arg);
|
||||
if (!path)
|
||||
return log_oom();
|
||||
|
||||
@@ -1099,159 +1045,147 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
}
|
||||
|
||||
case 'q':
|
||||
arg_query = query_type_from_string(optarg);
|
||||
if (arg_query < 0) {
|
||||
if (streq(optarg, "env")) /* deprecated */
|
||||
arg_query = QUERY_PROPERTY;
|
||||
else
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown query type '%s'", optarg);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
OPTION('r', "root", NULL, "Prepend dev directory to path names"):
|
||||
arg_root = true;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
OPTION('a', "attribute-walk", NULL,
|
||||
"Print all key matches walking along the chain of parent devices"):
|
||||
arg_action_type = ACTION_ATTRIBUTE_WALK;
|
||||
break;
|
||||
|
||||
OPTION('t', "tree", NULL, "Show tree of devices"):
|
||||
arg_action_type = ACTION_TREE;
|
||||
break;
|
||||
|
||||
OPTION('d', "device-id-of-file", "FILE",
|
||||
"Print major:minor of device containing this file"):
|
||||
arg_action_type = ACTION_DEVICE_ID_FILE;
|
||||
r = free_and_strdup(&arg_name, optarg);
|
||||
r = free_and_strdup(&arg_name, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
arg_action_type = ACTION_ATTRIBUTE_WALK;
|
||||
OPTION('x', "export", NULL, "Export key/value pairs"):
|
||||
arg_export = true;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
arg_action_type = ACTION_TREE;
|
||||
OPTION('P', "export-prefix", "NAME", "Export the key name with a prefix"):
|
||||
arg_export = true;
|
||||
arg_export_prefix = opts.arg;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
OPTION('e', "export-db", NULL, "Export the content of the udev database"):
|
||||
arg_action_type = ACTION_EXPORT;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
OPTION('c', "cleanup-db", NULL, "Clean up the udev database"):
|
||||
arg_action_type = ACTION_CLEANUP_DB;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
arg_export = true;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
arg_export = true;
|
||||
arg_export_prefix = optarg;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
if (optarg) {
|
||||
r = parse_sec(optarg, &arg_wait_for_initialization_timeout);
|
||||
OPTION_FULL(OPTION_OPTIONAL_ARG, 'w', "wait-for-initialization", "SECS",
|
||||
"Wait for device to be initialized"):
|
||||
if (opts.arg) {
|
||||
r = parse_sec(opts.arg, &arg_wait_for_initialization_timeout);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse timeout value: %m");
|
||||
} else
|
||||
arg_wait_for_initialization_timeout = USEC_INFINITY;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
return print_version();
|
||||
|
||||
case 'h':
|
||||
return help();
|
||||
|
||||
case ARG_NO_PAGER:
|
||||
OPTION_COMMON_NO_PAGER:
|
||||
arg_pager_flags |= PAGER_DISABLE;
|
||||
break;
|
||||
|
||||
case ARG_JSON:
|
||||
r = parse_json_argument(optarg, &arg_json_format_flags);
|
||||
OPTION_COMMON_JSON:
|
||||
r = parse_json_argument(opts.arg, &arg_json_format_flags);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
break;
|
||||
|
||||
case ARG_SUBSYSTEM_MATCH:
|
||||
r = strv_extend(&arg_subsystem_match, optarg);
|
||||
OPTION_LONG("subsystem-match", "SUBSYSTEM",
|
||||
"Query devices matching a subsystem"):
|
||||
r = strv_extend(&arg_subsystem_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case ARG_SUBSYSTEM_NOMATCH:
|
||||
r = strv_extend(&arg_subsystem_nomatch, optarg);
|
||||
OPTION_LONG("subsystem-nomatch", "SUBSYSTEM",
|
||||
"Query devices not matching a subsystem"):
|
||||
r = strv_extend(&arg_subsystem_nomatch, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case ARG_ATTR_MATCH:
|
||||
if (!strchr(optarg, '='))
|
||||
OPTION_LONG("attr-match", "FILE[=VALUE]",
|
||||
"Query devices that match an attribute"):
|
||||
if (!strchr(opts.arg, '='))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Expected <ATTR>=<value> instead of '%s'", optarg);
|
||||
"Expected <ATTR>=<value> instead of '%s'", opts.arg);
|
||||
|
||||
r = strv_extend(&arg_attr_match, optarg);
|
||||
r = strv_extend(&arg_attr_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case ARG_ATTR_NOMATCH:
|
||||
if (!strchr(optarg, '='))
|
||||
OPTION_LONG("attr-nomatch", "FILE[=VALUE]",
|
||||
"Query devices that do not match an attribute"):
|
||||
if (!strchr(opts.arg, '='))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Expected <ATTR>=<value> instead of '%s'", optarg);
|
||||
"Expected <ATTR>=<value> instead of '%s'", opts.arg);
|
||||
|
||||
r = strv_extend(&arg_attr_nomatch, optarg);
|
||||
r = strv_extend(&arg_attr_nomatch, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case ARG_PROPERTY_MATCH:
|
||||
if (!strchr(optarg, '='))
|
||||
OPTION_LONG("property-match", "KEY=VALUE",
|
||||
"Query devices with matching properties"):
|
||||
if (!strchr(opts.arg, '='))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Expected <PROPERTY>=<value> instead of '%s'", optarg);
|
||||
"Expected <PROPERTY>=<value> instead of '%s'", opts.arg);
|
||||
|
||||
r = strv_extend(&arg_property_match, optarg);
|
||||
r = strv_extend(&arg_property_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case ARG_TAG_MATCH:
|
||||
r = strv_extend(&arg_tag_match, optarg);
|
||||
OPTION_LONG("tag-match", "TAG", "Query devices with a matching tag"):
|
||||
r = strv_extend(&arg_tag_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case ARG_SYSNAME_MATCH:
|
||||
r = strv_extend(&arg_sysname_match, optarg);
|
||||
OPTION_LONG("sysname-match", "NAME", "Query devices with this /sys path"):
|
||||
r = strv_extend(&arg_sysname_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case ARG_NAME_MATCH:
|
||||
r = strv_extend(&arg_name_match, optarg);
|
||||
OPTION_LONG("name-match", "NAME", "Query devices with this /dev name"):
|
||||
r = strv_extend(&arg_name_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case ARG_PARENT_MATCH:
|
||||
r = strv_extend(&arg_parent_match, optarg);
|
||||
OPTION_LONG("parent-match", "NAME", "Query devices with this parent device"):
|
||||
r = strv_extend(&arg_parent_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case ARG_INITIALIZED_MATCH:
|
||||
OPTION_LONG("initialized-match", NULL,
|
||||
"Query devices that are already initialized"):
|
||||
arg_initialized_match = MATCH_INITIALIZED_YES;
|
||||
break;
|
||||
|
||||
case ARG_INITIALIZED_NOMATCH:
|
||||
OPTION_LONG("initialized-nomatch", NULL,
|
||||
"Query devices that are not initialized yet"):
|
||||
arg_initialized_match = MATCH_INITIALIZED_NO;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
r = strv_extend_strv(&arg_devices, argv + optind, /* filter_duplicates= */ false);
|
||||
r = strv_extend_strv(&arg_devices, option_parser_get_args(&opts), /* filter_duplicates= */ false);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to build argument list: %m");
|
||||
|
||||
|
||||
+35
-56
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
@@ -9,11 +8,14 @@
|
||||
#include "device-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fdset.h"
|
||||
#include "format-table.h"
|
||||
#include "glyph-util.h"
|
||||
#include "hash-funcs.h"
|
||||
#include "help-util.h"
|
||||
#include "lock-util.h"
|
||||
#include "options.h"
|
||||
#include "path-util.h"
|
||||
#include "pidref.h"
|
||||
#include "pretty-print.h"
|
||||
#include "process-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "sort-util.h"
|
||||
@@ -33,70 +35,52 @@ STATIC_DESTRUCTOR_REGISTER(arg_backing, strv_freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_cmdline, strv_freep);
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = terminal_urlify_man("udevadm", "8", &link);
|
||||
r = option_parser_get_help_table_ns("udevadm-lock", &options);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
return r;
|
||||
|
||||
printf("%s [OPTIONS...] COMMAND\n"
|
||||
"%s [OPTIONS...] --print\n"
|
||||
"\n%sLock a block device and run a command.%s\n\n"
|
||||
" -h --help Print this message\n"
|
||||
" -V --version Print version of the program\n"
|
||||
" -d --device=DEVICE Block device to lock\n"
|
||||
" -b --backing=FILE File whose backing block device to lock\n"
|
||||
" -t --timeout=SECS Block at most the specified time waiting for lock\n"
|
||||
" -p --print Only show which block device the lock would be taken on\n"
|
||||
"\nSee the %s for details.\n",
|
||||
program_invocation_short_name,
|
||||
program_invocation_short_name,
|
||||
ansi_highlight(),
|
||||
ansi_normal(),
|
||||
link);
|
||||
help_cmdline("lock [OPTIONS...] COMMAND");
|
||||
help_cmdline("lock [OPTIONS...] --print");
|
||||
help_abstract("Lock a block device and run a command.");
|
||||
help_section("Options:");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_man_page_reference("udevadm", "8");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "device", required_argument, NULL, 'd' },
|
||||
{ "backing", required_argument, NULL, 'b' },
|
||||
{ "timeout", required_argument, NULL, 't' },
|
||||
{ "print", no_argument, NULL, 'p' },
|
||||
{}
|
||||
};
|
||||
|
||||
int c, r;
|
||||
int r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
/* Resetting to 0 forces the invocation of an internal initialization routine of getopt_long()
|
||||
* that checks for GNU extensions in optstring ('-' or '+' at the beginning). */
|
||||
optind = 0;
|
||||
while ((c = getopt_long(argc, argv, arg_print ? "hVd:b:t:p" : "+hVd:b:t:p", options, NULL)) >= 0)
|
||||
OptionParser opts = { argc, argv, OPTION_PARSER_STOP_AT_FIRST_NONOPTION, "udevadm-lock" };
|
||||
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
|
||||
case 'h':
|
||||
OPTION_NAMESPACE("udevadm-lock"): {}
|
||||
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
case 'V':
|
||||
OPTION('V', "version", NULL, "Show package version"):
|
||||
return print_version();
|
||||
|
||||
case 'd':
|
||||
case 'b': {
|
||||
OPTION('d', "device", "DEVICE", "Block device to lock"): {} /* fall through */
|
||||
OPTION('b', "backing", "FILE", "File whose backing block device to lock"): {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
char ***l = c == 'd' ? &arg_devices : &arg_backing;
|
||||
char ***l = opts.opt->short_code == 'd' ? &arg_devices : &arg_backing;
|
||||
|
||||
r = path_make_absolute_cwd(optarg, &s);
|
||||
r = path_make_absolute_cwd(opts.arg, &s);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to make path '%s' absolute: %m", optarg);
|
||||
return log_error_errno(r, "Failed to make path '%s' absolute: %m", opts.arg);
|
||||
|
||||
path_simplify(s);
|
||||
|
||||
@@ -107,31 +91,26 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
break;
|
||||
}
|
||||
|
||||
case 't':
|
||||
r = parse_sec(optarg, &arg_timeout_usec);
|
||||
OPTION('t', "timeout", "SECS", "Block at most the specified time waiting for lock"):
|
||||
r = parse_sec(opts.arg, &arg_timeout_usec);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse --timeout= parameter: %s", optarg);
|
||||
return log_error_errno(r, "Failed to parse --timeout= parameter: %s", opts.arg);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
OPTION('p', "print", NULL, "Only show which block device the lock would be taken on"):
|
||||
arg_print = true;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
char **args = option_parser_get_args(&opts);
|
||||
if (arg_print) {
|
||||
if (optind != argc)
|
||||
if (!strv_isempty(args))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No arguments expected.");
|
||||
} else {
|
||||
if (optind + 1 > argc)
|
||||
if (strv_isempty(args))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Too few arguments, command to execute.");
|
||||
|
||||
arg_cmdline = strv_copy(argv + optind);
|
||||
arg_cmdline = strv_copy(args);
|
||||
if (!arg_cmdline)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
+47
-44
@@ -1,7 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include "sd-device.h"
|
||||
#include "sd-event.h"
|
||||
|
||||
@@ -9,8 +7,11 @@
|
||||
#include "device-monitor-private.h"
|
||||
#include "device-private.h"
|
||||
#include "device-util.h"
|
||||
#include "format-table.h"
|
||||
#include "format-util.h"
|
||||
#include "hashmap.h"
|
||||
#include "help-util.h"
|
||||
#include "options.h"
|
||||
#include "set.h"
|
||||
#include "static-destruct.h"
|
||||
#include "string-util.h"
|
||||
@@ -99,60 +100,70 @@ static int setup_monitor(MonitorNetlinkGroup sender, sd_event *event, sd_device_
|
||||
}
|
||||
|
||||
static int help(void) {
|
||||
printf("%s monitor [OPTIONS]\n\n"
|
||||
"Listen to kernel and udev events.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" -V --version Show package version\n"
|
||||
" -p --property Print the event properties\n"
|
||||
" -k --kernel Print kernel uevents\n"
|
||||
" -u --udev Print udev events\n"
|
||||
" -s --subsystem-match=SUBSYSTEM[/DEVTYPE] Filter events by subsystem\n"
|
||||
" -t --tag-match=TAG Filter events by tag\n",
|
||||
program_invocation_short_name);
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = option_parser_get_help_table_ns("udevadm-monitor", &options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_cmdline("monitor [OPTIONS]");
|
||||
help_abstract("Listen to kernel and udev events.");
|
||||
help_section("Options:");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_man_page_reference("udevadm", "8");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
static const struct option options[] = {
|
||||
{ "property", no_argument, NULL, 'p' },
|
||||
{ "environment", no_argument, NULL, 'e' }, /* alias for -p */
|
||||
{ "kernel", no_argument, NULL, 'k' },
|
||||
{ "udev", no_argument, NULL, 'u' },
|
||||
{ "subsystem-match", required_argument, NULL, 's' },
|
||||
{ "tag-match", required_argument, NULL, 't' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{}
|
||||
};
|
||||
int r;
|
||||
|
||||
int r, c;
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "pekus:t:Vh", options, NULL)) >= 0)
|
||||
OptionParser opts = { argc, argv, .namespace = "udevadm-monitor" };
|
||||
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
case 'p':
|
||||
case 'e':
|
||||
|
||||
OPTION_NAMESPACE("udevadm-monitor"): {}
|
||||
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
OPTION('V', "version", NULL, "Show package version"):
|
||||
return print_version();
|
||||
|
||||
OPTION('e', "environment", NULL, /* help= */ NULL): {} /* hidden alias for -p */
|
||||
OPTION('p', "property", NULL, "Print the event properties"):
|
||||
arg_show_property = true;
|
||||
break;
|
||||
case 'k':
|
||||
|
||||
OPTION('k', "kernel", NULL, "Print kernel uevents"):
|
||||
arg_print_kernel = true;
|
||||
break;
|
||||
case 'u':
|
||||
|
||||
OPTION('u', "udev", NULL, "Print udev events"):
|
||||
arg_print_udev = true;
|
||||
break;
|
||||
case 's': {
|
||||
|
||||
OPTION('s', "subsystem-match", "SUBSYSTEM[/DEVTYPE]",
|
||||
"Filter events by subsystem"): {
|
||||
_cleanup_free_ char *subsystem = NULL, *devtype = NULL;
|
||||
const char *slash;
|
||||
|
||||
slash = strchr(optarg, '/');
|
||||
slash = strchr(opts.arg, '/');
|
||||
if (slash) {
|
||||
devtype = strdup(slash + 1);
|
||||
if (!devtype)
|
||||
return log_oom();
|
||||
|
||||
subsystem = strndup(optarg, slash - optarg);
|
||||
subsystem = strndup(opts.arg, slash - opts.arg);
|
||||
} else
|
||||
subsystem = strdup(optarg);
|
||||
subsystem = strdup(opts.arg);
|
||||
|
||||
if (!subsystem)
|
||||
return log_oom();
|
||||
@@ -165,20 +176,12 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
TAKE_PTR(devtype);
|
||||
break;
|
||||
}
|
||||
case 't':
|
||||
r = set_put_strdup(&arg_tag_filter, optarg);
|
||||
|
||||
OPTION('t', "tag-match", "TAG", "Filter events by tag"):
|
||||
r = set_put_strdup(&arg_tag_filter, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
return print_version();
|
||||
case 'h':
|
||||
return help();
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
if (!arg_print_kernel && !arg_print_udev) {
|
||||
|
||||
+47
-42
@@ -4,7 +4,6 @@
|
||||
* Copyright © 2009 Scott James Remnant <scott@netsplit.com>
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
@@ -14,6 +13,9 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "bus-util.h"
|
||||
#include "format-table.h"
|
||||
#include "help-util.h"
|
||||
#include "options.h"
|
||||
#include "path-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
@@ -28,60 +30,63 @@ static usec_t arg_timeout_usec = 120 * USEC_PER_SEC;
|
||||
static const char *arg_exists = NULL;
|
||||
|
||||
static int help(void) {
|
||||
printf("%s settle [OPTIONS]\n\n"
|
||||
"Wait for pending udev events.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" -V --version Show package version\n"
|
||||
" -t --timeout=SEC Maximum time to wait for events\n"
|
||||
" -E --exit-if-exists=FILE Stop waiting if file exists\n",
|
||||
program_invocation_short_name);
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = option_parser_get_help_table_ns("udevadm-settle", &options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_cmdline("settle [OPTIONS]");
|
||||
help_abstract("Wait for pending udev events.");
|
||||
help_section("Options:");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_man_page_reference("udevadm", "8");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
static const struct option options[] = {
|
||||
{ "timeout", required_argument, NULL, 't' },
|
||||
{ "exit-if-exists", required_argument, NULL, 'E' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "seq-start", required_argument, NULL, 's' }, /* removed */
|
||||
{ "seq-end", required_argument, NULL, 'e' }, /* removed */
|
||||
{ "quiet", no_argument, NULL, 'q' }, /* removed */
|
||||
{}
|
||||
};
|
||||
int r;
|
||||
|
||||
int c, r;
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "t:E:Vhs:e:q", options, NULL)) >= 0) {
|
||||
OptionParser opts = { argc, argv, .namespace = "udevadm-settle" };
|
||||
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
case 't':
|
||||
r = parse_sec(optarg, &arg_timeout_usec);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse timeout value '%s': %m", optarg);
|
||||
break;
|
||||
case 'E':
|
||||
if (!path_is_valid(optarg))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid path: %s", optarg);
|
||||
|
||||
arg_exists = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
return print_version();
|
||||
case 'h':
|
||||
OPTION_NAMESPACE("udevadm-settle"): {}
|
||||
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
case 's':
|
||||
case 'e':
|
||||
case 'q':
|
||||
|
||||
OPTION('V', "version", NULL, "Show package version"):
|
||||
return print_version();
|
||||
|
||||
OPTION('t', "timeout", "SEC", "Maximum time to wait for events"):
|
||||
r = parse_sec(opts.arg, &arg_timeout_usec);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse timeout value '%s': %m", opts.arg);
|
||||
break;
|
||||
|
||||
OPTION('E', "exit-if-exists", "FILE", "Stop waiting if file exists"):
|
||||
if (!path_is_valid(opts.arg))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid path: %s", opts.arg);
|
||||
|
||||
arg_exists = opts.arg;
|
||||
break;
|
||||
|
||||
OPTION('s', "seq-start", "ARG", NULL): {} /* removed */
|
||||
OPTION('e', "seq-end", "ARG", NULL): {} /* removed */
|
||||
OPTION('q', "quiet", NULL, NULL): /* removed */
|
||||
return log_info_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Option -%c no longer supported.",
|
||||
c);
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
default:
|
||||
assert_not_reached();
|
||||
opts.opt->short_code);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "device-private.h"
|
||||
#include "device-util.h"
|
||||
#include "format-table.h"
|
||||
#include "help-util.h"
|
||||
#include "log.h"
|
||||
#include "options.h"
|
||||
#include "udev-builtin.h"
|
||||
#include "udevadm.h"
|
||||
#include "udevadm-util.h"
|
||||
@@ -15,51 +15,57 @@ static const char *arg_command = NULL;
|
||||
static const char *arg_syspath = NULL;
|
||||
|
||||
static int help(void) {
|
||||
printf("%s test-builtin [OPTIONS] COMMAND DEVPATH\n\n"
|
||||
"Test a built-in command.\n\n"
|
||||
" -h --help Print this message\n"
|
||||
" -V --version Print version of the program\n"
|
||||
" -a --action=ACTION|help Set action string\n"
|
||||
"\nCommands:\n",
|
||||
program_invocation_short_name);
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = option_parser_get_help_table_ns("udevadm-test-builtin", &options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_cmdline("test-builtin [OPTIONS] COMMAND DEVPATH");
|
||||
help_abstract("Test a built-in command.");
|
||||
help_section("Options:");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_section("Commands:");
|
||||
udev_builtin_list();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
static const struct option options[] = {
|
||||
{ "action", required_argument, NULL, 'a' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{}
|
||||
};
|
||||
int r;
|
||||
|
||||
int r, c;
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "a:Vh", options, NULL)) >= 0)
|
||||
OptionParser opts = { argc, argv, .namespace = "udevadm-test-builtin" };
|
||||
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
case 'a':
|
||||
r = parse_device_action(optarg, &arg_action);
|
||||
|
||||
OPTION_NAMESPACE("udevadm-test-builtin"): {}
|
||||
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
OPTION('V', "version", NULL, "Show package version"):
|
||||
return print_version();
|
||||
|
||||
OPTION('a', "action", "ACTION|help", "Set action string"):
|
||||
r = parse_device_action(opts.arg, &arg_action);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
break;
|
||||
case 'V':
|
||||
return print_version();
|
||||
case 'h':
|
||||
return help();
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
if (argc != optind + 2)
|
||||
if (option_parser_get_n_args(&opts) != 2)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Expected two arguments: command string and device path.");
|
||||
|
||||
arg_command = ASSERT_PTR(argv[optind]);
|
||||
arg_syspath = ASSERT_PTR(argv[optind+1]);
|
||||
char **args = option_parser_get_args(&opts);
|
||||
arg_command = ASSERT_PTR(args[0]);
|
||||
arg_syspath = ASSERT_PTR(args[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+45
-44
@@ -3,7 +3,6 @@
|
||||
* Copyright © 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -12,7 +11,10 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "device-private.h"
|
||||
#include "format-table.h"
|
||||
#include "help-util.h"
|
||||
#include "log.h"
|
||||
#include "options.h"
|
||||
#include "parse-argument.h"
|
||||
#include "static-destruct.h"
|
||||
#include "strv.h"
|
||||
@@ -33,55 +35,59 @@ static sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF;
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_extra_rules_dir, strv_freep);
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
printf("%s test [OPTIONS] DEVPATH\n\n"
|
||||
"Test an event run.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" -V --version Show package version\n"
|
||||
" -a --action=ACTION|help Set action string\n"
|
||||
" -N --resolve-names=early|late|never When to resolve names\n"
|
||||
" -D --extra-rules-dir=DIR Also load rules from the directory\n"
|
||||
" -v --verbose Show verbose logs\n"
|
||||
" --json=pretty|short|off Generate JSON output\n",
|
||||
program_invocation_short_name);
|
||||
r = option_parser_get_help_table_ns("udevadm-test", &options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_cmdline("test [OPTIONS] DEVPATH");
|
||||
help_abstract("Test an event run.");
|
||||
help_section("Options:");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_man_page_reference("udevadm", "8");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_JSON = 0x100,
|
||||
};
|
||||
int r;
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "action", required_argument, NULL, 'a' },
|
||||
{ "resolve-names", required_argument, NULL, 'N' },
|
||||
{ "extra-rules-dir", required_argument, NULL, 'D' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "json", required_argument, NULL, ARG_JSON },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{}
|
||||
};
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
int r, c;
|
||||
OptionParser opts = { argc, argv, .namespace = "udevadm-test" };
|
||||
|
||||
while ((c = getopt_long(argc, argv, "a:N:D:vVh", options, NULL)) >= 0)
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
case 'a':
|
||||
r = parse_device_action(optarg, &arg_action);
|
||||
|
||||
OPTION_NAMESPACE("udevadm-test"): {}
|
||||
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
OPTION('V', "version", NULL, "Show package version"):
|
||||
return print_version();
|
||||
|
||||
OPTION('a', "action", "ACTION|help", "Set action string"):
|
||||
r = parse_device_action(opts.arg, &arg_action);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
break;
|
||||
case 'N':
|
||||
r = parse_resolve_name_timing(optarg, &arg_resolve_name_timing);
|
||||
|
||||
OPTION_COMMON_RESOLVE_NAMES:
|
||||
r = parse_resolve_name_timing(opts.arg, &arg_resolve_name_timing);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
break;
|
||||
case 'D': {
|
||||
|
||||
OPTION('D', "extra-rules-dir", "DIR", "Also load rules from the directory"): {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
|
||||
r = parse_path_argument(optarg, /* suppress_root= */ false, &p);
|
||||
r = parse_path_argument(opts.arg, /* suppress_root= */ false, &p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -90,25 +96,20 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return log_oom();
|
||||
break;
|
||||
}
|
||||
case 'v':
|
||||
|
||||
OPTION('v', "verbose", NULL, "Show verbose logs"):
|
||||
arg_verbose = true;
|
||||
break;
|
||||
case ARG_JSON:
|
||||
r = parse_json_argument(optarg, &arg_json_format_flags);
|
||||
|
||||
OPTION_COMMON_JSON:
|
||||
r = parse_json_argument(opts.arg, &arg_json_format_flags);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
break;
|
||||
case 'V':
|
||||
return print_version();
|
||||
case 'h':
|
||||
return help();
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
arg_syspath = argv[optind];
|
||||
char **args = option_parser_get_args(&opts);
|
||||
arg_syspath = args[0];
|
||||
if (!arg_syspath)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "syspath parameter missing.");
|
||||
|
||||
|
||||
+95
-137
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "sd-device.h"
|
||||
@@ -10,7 +9,10 @@
|
||||
#include "device-enumerator-private.h"
|
||||
#include "device-private.h"
|
||||
#include "device-util.h"
|
||||
#include "format-table.h"
|
||||
#include "help-util.h"
|
||||
#include "id128-util.h"
|
||||
#include "options.h"
|
||||
#include "set.h"
|
||||
#include "static-destruct.h"
|
||||
#include "string-table.h"
|
||||
@@ -320,214 +322,170 @@ static int setup_matches(sd_device_enumerator *e) {
|
||||
}
|
||||
|
||||
static int help(void) {
|
||||
printf("%s trigger [OPTIONS] DEVPATH\n\n"
|
||||
"Request events from the kernel.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" -V --version Show package version\n"
|
||||
" -v --verbose Print the list of devices while running\n"
|
||||
" -n --dry-run Do not actually trigger the events\n"
|
||||
" -q --quiet Suppress error logging in triggering events\n"
|
||||
" -t --type= Type of events to trigger\n"
|
||||
" devices sysfs devices (default)\n"
|
||||
" subsystems sysfs subsystems and drivers\n"
|
||||
" all sysfs devices, subsystems, and drivers\n"
|
||||
" -c --action=ACTION|help Event action value, default is \"change\"\n"
|
||||
" -s --subsystem-match=SUBSYSTEM Trigger devices from a matching subsystem\n"
|
||||
" -S --subsystem-nomatch=SUBSYSTEM Exclude devices from a matching subsystem\n"
|
||||
" -a --attr-match=FILE[=VALUE] Trigger devices with a matching attribute\n"
|
||||
" -A --attr-nomatch=FILE[=VALUE] Exclude devices with a matching attribute\n"
|
||||
" -p --property-match=KEY=VALUE Trigger devices with a matching property\n"
|
||||
" -g --tag-match=TAG Trigger devices with a matching tag\n"
|
||||
" -y --sysname-match=NAME Trigger devices with this /sys path\n"
|
||||
" --name-match=NAME Trigger devices with this /dev name\n"
|
||||
" -b --parent-match=NAME Trigger devices with that parent device\n"
|
||||
" --include-parents Trigger parent devices of found devices\n"
|
||||
" --initialized-match Trigger devices that are already initialized\n"
|
||||
" --initialized-nomatch Trigger devices that are not initialized yet\n"
|
||||
" -w --settle Wait for the triggered events to complete\n"
|
||||
" --wait-daemon[=SECONDS] Wait for udevd daemon to be initialized\n"
|
||||
" before triggering uevents\n"
|
||||
" --uuid Print synthetic uevent UUID\n"
|
||||
" --prioritized-subsystem=SUBSYSTEM[,SUBSYSTEM…]\n"
|
||||
" Trigger devices from a matching subsystem first\n",
|
||||
program_invocation_short_name);
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = option_parser_get_help_table_ns("udevadm-trigger", &options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_cmdline("trigger [OPTIONS] DEVPATH");
|
||||
help_abstract("Request events from the kernel.");
|
||||
help_section("Options:");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_man_page_reference("udevadm", "8");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_NAME = 0x100,
|
||||
ARG_PING,
|
||||
ARG_UUID,
|
||||
ARG_PRIORITIZED_SUBSYSTEM,
|
||||
ARG_INITIALIZED_MATCH,
|
||||
ARG_INITIALIZED_NOMATCH,
|
||||
ARG_INCLUDE_PARENTS,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "dry-run", no_argument, NULL, 'n' },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "type", required_argument, NULL, 't' },
|
||||
{ "action", required_argument, NULL, 'c' },
|
||||
{ "subsystem-match", required_argument, NULL, 's' },
|
||||
{ "subsystem-nomatch", required_argument, NULL, 'S' },
|
||||
{ "attr-match", required_argument, NULL, 'a' },
|
||||
{ "attr-nomatch", required_argument, NULL, 'A' },
|
||||
{ "property-match", required_argument, NULL, 'p' },
|
||||
{ "tag-match", required_argument, NULL, 'g' },
|
||||
{ "sysname-match", required_argument, NULL, 'y' },
|
||||
{ "name-match", required_argument, NULL, ARG_NAME },
|
||||
{ "parent-match", required_argument, NULL, 'b' },
|
||||
{ "include-parents", no_argument, NULL, ARG_INCLUDE_PARENTS },
|
||||
{ "initialized-match", no_argument, NULL, ARG_INITIALIZED_MATCH },
|
||||
{ "initialized-nomatch", no_argument, NULL, ARG_INITIALIZED_NOMATCH },
|
||||
{ "settle", no_argument, NULL, 'w' },
|
||||
{ "wait-daemon", optional_argument, NULL, ARG_PING },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "uuid", no_argument, NULL, ARG_UUID },
|
||||
{ "prioritized-subsystem", required_argument, NULL, ARG_PRIORITIZED_SUBSYSTEM },
|
||||
{}
|
||||
};
|
||||
|
||||
int c, r;
|
||||
int r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "vnqt:c:s:S:a:A:p:g:y:b:wVh", options, NULL)) >= 0) {
|
||||
OptionParser opts = { argc, argv, .namespace = "udevadm-trigger" };
|
||||
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
case 'v':
|
||||
|
||||
OPTION_NAMESPACE("udevadm-trigger"): {}
|
||||
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
OPTION('V', "version", NULL, "Show package version"):
|
||||
return print_version();
|
||||
|
||||
OPTION('v', "verbose", NULL, "Print the list of devices while running"):
|
||||
arg_verbose = true;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
OPTION('n', "dry-run", NULL, "Do not actually trigger the events"):
|
||||
arg_dry_run = true;
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
OPTION('q', "quiet", NULL, "Suppress error logging in triggering events"):
|
||||
arg_quiet = true;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
arg_scan_type = scan_type_from_string(optarg);
|
||||
OPTION('t', "type", "TYPE", "Type of sysfs events to trigger:"): {}
|
||||
OPTION_HELP_VERBATIM(" devices", "- devices (default)"): {}
|
||||
OPTION_HELP_VERBATIM(" subsystems", "- subsystems and drivers"): {}
|
||||
OPTION_HELP_VERBATIM(" all", "- devices, subsystems, and drivers"):
|
||||
arg_scan_type = scan_type_from_string(opts.arg);
|
||||
if (arg_scan_type < 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown type --type=%s", optarg);
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown type --type=%s", opts.arg);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
r = parse_device_action(optarg, &arg_action);
|
||||
OPTION('c', "action", "ACTION|help", "Event action value, default is \"change\""):
|
||||
r = parse_device_action(opts.arg, &arg_action);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
r = strv_extend(&arg_subsystem_match, optarg);
|
||||
OPTION('s', "subsystem-match", "SUBSYSTEM",
|
||||
"Trigger devices from a matching subsystem"):
|
||||
r = strv_extend(&arg_subsystem_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
r = strv_extend(&arg_subsystem_nomatch, optarg);
|
||||
OPTION('S', "subsystem-nomatch", "SUBSYSTEM",
|
||||
"Exclude devices from a matching subsystem"):
|
||||
r = strv_extend(&arg_subsystem_nomatch, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
r = strv_extend(&arg_attr_match, optarg);
|
||||
OPTION('a', "attr-match", "FILE[=VALUE]",
|
||||
"Trigger devices with a matching attribute"):
|
||||
r = strv_extend(&arg_attr_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
r = strv_extend(&arg_attr_nomatch, optarg);
|
||||
OPTION('A', "attr-nomatch", "FILE[=VALUE]",
|
||||
"Exclude devices with a matching attribute"):
|
||||
r = strv_extend(&arg_attr_nomatch, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
r = strv_extend(&arg_property_match, optarg);
|
||||
OPTION('p', "property-match", "KEY=VALUE",
|
||||
"Trigger devices with a matching property"):
|
||||
r = strv_extend(&arg_property_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
r = strv_extend(&arg_tag_match, optarg);
|
||||
OPTION('g', "tag-match", "TAG", "Trigger devices with a matching tag"):
|
||||
r = strv_extend(&arg_tag_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
r = strv_extend(&arg_sysname_match, optarg);
|
||||
OPTION('y', "sysname-match", "NAME", "Trigger devices with this /sys path"):
|
||||
r = strv_extend(&arg_sysname_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
r = strv_extend(&arg_parent_match, optarg);
|
||||
OPTION_LONG("name-match", "NAME", "Trigger devices with this /dev name"):
|
||||
r = strv_extend(&arg_name_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case ARG_INCLUDE_PARENTS:
|
||||
OPTION('b', "parent-match", "NAME", "Trigger devices with that parent device"):
|
||||
r = strv_extend(&arg_parent_match, opts.arg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
OPTION_LONG("include-parents", NULL, "Trigger parent devices of found devices"):
|
||||
arg_include_parents = true;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
arg_settle = true;
|
||||
break;
|
||||
|
||||
case ARG_NAME:
|
||||
r = strv_extend(&arg_name_match, optarg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case ARG_PING:
|
||||
arg_ping = true;
|
||||
if (optarg) {
|
||||
r = parse_sec(optarg, &arg_ping_timeout_usec);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed to parse timeout value '%s', ignoring: %m", optarg);
|
||||
}
|
||||
break;
|
||||
|
||||
case ARG_UUID:
|
||||
arg_uuid = true;
|
||||
break;
|
||||
|
||||
case ARG_PRIORITIZED_SUBSYSTEM:
|
||||
r = strv_split_and_extend(&arg_prioritized_subsystems, optarg, ",", /* filter_duplicates= */ false);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
|
||||
case ARG_INITIALIZED_MATCH:
|
||||
OPTION_LONG("initialized-match", NULL,
|
||||
"Trigger devices that are already initialized"):
|
||||
arg_initialized_match = MATCH_INITIALIZED_YES;
|
||||
break;
|
||||
|
||||
case ARG_INITIALIZED_NOMATCH:
|
||||
OPTION_LONG("initialized-nomatch", NULL,
|
||||
"Trigger devices that are not initialized yet"):
|
||||
arg_initialized_match = MATCH_INITIALIZED_NO;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
return print_version();
|
||||
OPTION('w', "settle", NULL, "Wait for the triggered events to complete"):
|
||||
arg_settle = true;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
return help();
|
||||
OPTION_LONG_FLAGS(OPTION_OPTIONAL_ARG, "wait-daemon", "SECONDS",
|
||||
"Wait for udevd daemon to be initialized before triggering uevents"):
|
||||
arg_ping = true;
|
||||
if (opts.arg) {
|
||||
r = parse_sec(opts.arg, &arg_ping_timeout_usec);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed to parse timeout value '%s', ignoring: %m", opts.arg);
|
||||
}
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
OPTION_LONG("uuid", NULL, "Print synthetic uevent UUID"):
|
||||
arg_uuid = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
OPTION_LONG("prioritized-subsystem", "SUBSYSTEM[,SUBSYSTEM…]",
|
||||
"Trigger devices from a matching subsystem first"):
|
||||
r = strv_split_and_extend(&arg_prioritized_subsystems, opts.arg, ",", /* filter_duplicates= */ false);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r = strv_extend_strv(&arg_devices, argv + optind, /* filter_duplicates= */ false);
|
||||
r = strv_extend_strv(&arg_devices, option_parser_get_args(&opts), /* filter_duplicates= */ false);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to build argument list: %m");
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ int parse_resolve_name_timing(const char *str, ResolveNameTiming *ret) {
|
||||
if (streq(str, "help"))
|
||||
return DUMP_STRING_TABLE(resolve_name_timing, ResolveNameTiming, _RESOLVE_NAME_TIMING_MAX);
|
||||
|
||||
ResolveNameTiming v = resolve_name_timing_from_string(optarg);
|
||||
ResolveNameTiming v = resolve_name_timing_from_string(str);
|
||||
if (v < 0)
|
||||
return log_error_errno(v, "--resolve-names= must be 'early', 'late', or 'never'.");
|
||||
|
||||
|
||||
+39
-52
@@ -1,16 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "conf-files.h"
|
||||
#include "errno-util.h"
|
||||
#include "format-table.h"
|
||||
#include "help-util.h"
|
||||
#include "log.h"
|
||||
#include "options.h"
|
||||
#include "parse-argument.h"
|
||||
#include "pretty-print.h"
|
||||
#include "static-destruct.h"
|
||||
#include "strv.h"
|
||||
#include "udev-rules.h"
|
||||
#include "udevadm.h"
|
||||
#include "udevadm-util.h"
|
||||
@@ -23,81 +24,66 @@ static bool arg_style = true;
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = terminal_urlify_man("udevadm", "8", &link);
|
||||
r = option_parser_get_help_table_ns("udevadm-verify", &options);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
return r;
|
||||
|
||||
printf("%s verify [OPTIONS] [FILE...]\n"
|
||||
"\n%sVerify udev rules files.%s\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" -V --version Show package version\n"
|
||||
" -N --resolve-names=early|late|never When to resolve names\n"
|
||||
" --root=PATH Operate on an alternate filesystem root\n"
|
||||
" --no-summary Do not show summary\n"
|
||||
" --no-style Ignore style issues\n"
|
||||
"\nSee the %s for details.\n",
|
||||
program_invocation_short_name,
|
||||
ansi_highlight(),
|
||||
ansi_normal(),
|
||||
link);
|
||||
help_cmdline("verify [OPTIONS] [FILE...]");
|
||||
help_abstract("Verify udev rules files.");
|
||||
help_section("Options:");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_man_page_reference("udevadm", "8");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_ROOT = 0x100,
|
||||
ARG_NO_SUMMARY,
|
||||
ARG_NO_STYLE,
|
||||
};
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "resolve-names", required_argument, NULL, 'N' },
|
||||
{ "root", required_argument, NULL, ARG_ROOT },
|
||||
{ "no-summary", no_argument, NULL, ARG_NO_SUMMARY },
|
||||
{ "no-style", no_argument, NULL, ARG_NO_STYLE },
|
||||
{}
|
||||
};
|
||||
|
||||
int r, c;
|
||||
static int parse_argv(int argc, char *argv[], char ***remaining_args) {
|
||||
int r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
assert(remaining_args);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "hVN:", options, NULL)) >= 0)
|
||||
OptionParser opts = { argc, argv, .namespace = "udevadm-verify" };
|
||||
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
case 'h':
|
||||
|
||||
OPTION_NAMESPACE("udevadm-verify"): {}
|
||||
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
case 'V':
|
||||
|
||||
OPTION('V', "version", NULL, "Show package version"):
|
||||
return print_version();
|
||||
case 'N':
|
||||
r = parse_resolve_name_timing(optarg, &arg_resolve_name_timing);
|
||||
|
||||
OPTION_COMMON_RESOLVE_NAMES:
|
||||
r = parse_resolve_name_timing(opts.arg, &arg_resolve_name_timing);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
break;
|
||||
case ARG_ROOT:
|
||||
r = parse_path_argument(optarg, /* suppress_root= */ true, &arg_root);
|
||||
|
||||
OPTION_LONG("root", "PATH", "Operate on an alternate filesystem root"):
|
||||
r = parse_path_argument(opts.arg, /* suppress_root= */ true, &arg_root);
|
||||
if (r < 0)
|
||||
return r;
|
||||
break;
|
||||
case ARG_NO_SUMMARY:
|
||||
|
||||
OPTION_LONG("no-summary", NULL, "Do not show summary"):
|
||||
arg_summary = false;
|
||||
break;
|
||||
|
||||
case ARG_NO_STYLE:
|
||||
OPTION_LONG("no-style", NULL, "Ignore style issues"):
|
||||
arg_style = false;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
*remaining_args = option_parser_get_args(&opts);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -158,9 +144,10 @@ static int verify_rules(UdevRules *rules, ConfFile * const *files, size_t n_file
|
||||
|
||||
int verb_verify_main(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
_cleanup_(udev_rules_freep) UdevRules *rules = NULL;
|
||||
char **args = NULL;
|
||||
int r;
|
||||
|
||||
r = parse_argv(argc, argv);
|
||||
r = parse_argv(argc, argv, &args);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@@ -173,7 +160,7 @@ int verb_verify_main(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
|
||||
CLEANUP_ARRAY(files, n_files, conf_file_free_array);
|
||||
|
||||
r = search_rules_files(strv_skip(argv, optind), arg_root, &files, &n_files);
|
||||
r = search_rules_files(args, arg_root, &files, &n_files);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
+43
-49
@@ -1,7 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -10,7 +8,10 @@
|
||||
#include "device-monitor-private.h"
|
||||
#include "device-util.h"
|
||||
#include "event-util.h"
|
||||
#include "format-table.h"
|
||||
#include "fs-util.h"
|
||||
#include "help-util.h"
|
||||
#include "options.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "static-destruct.h"
|
||||
@@ -297,79 +298,72 @@ static int setup_periodic_timer(sd_event *event) {
|
||||
}
|
||||
|
||||
static int help(void) {
|
||||
printf("%s wait [OPTIONS] DEVICE [DEVICE…]\n\n"
|
||||
"Wait for devices or device symlinks being created.\n\n"
|
||||
" -h --help Print this message\n"
|
||||
" -V --version Print version of the program\n"
|
||||
" -t --timeout=SEC Maximum time to wait for the device\n"
|
||||
" --initialized=BOOL Wait for devices being initialized by systemd-udevd\n"
|
||||
" --removed Wait for devices being removed\n"
|
||||
" --settle Also wait for all queued events being processed\n",
|
||||
program_invocation_short_name);
|
||||
_cleanup_(table_unrefp) Table *options = NULL;
|
||||
int r;
|
||||
|
||||
r = option_parser_get_help_table_ns("udevadm-wait", &options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_cmdline("wait [OPTIONS] DEVICE [DEVICE…]");
|
||||
help_abstract("Wait for devices or device symlinks being created.");
|
||||
help_section("Options:");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_man_page_reference("udevadm", "8");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_INITIALIZED = 0x100,
|
||||
ARG_REMOVED,
|
||||
ARG_SETTLE,
|
||||
};
|
||||
int r;
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "timeout", required_argument, NULL, 't' },
|
||||
{ "initialized", required_argument, NULL, ARG_INITIALIZED },
|
||||
{ "removed", no_argument, NULL, ARG_REMOVED },
|
||||
{ "settle", no_argument, NULL, ARG_SETTLE },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{}
|
||||
};
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
int c, r;
|
||||
OptionParser opts = { argc, argv, .namespace = "udevadm-wait" };
|
||||
|
||||
while ((c = getopt_long(argc, argv, "t:hV", options, NULL)) >= 0)
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
case 't':
|
||||
r = parse_sec(optarg, &arg_timeout_usec);
|
||||
|
||||
OPTION_NAMESPACE("udevadm-wait"): {}
|
||||
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
OPTION('V', "version", NULL, "Show package version"):
|
||||
return print_version();
|
||||
|
||||
OPTION('t', "timeout", "SEC", "Maximum time to wait for the device"):
|
||||
r = parse_sec(opts.arg, &arg_timeout_usec);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse -t/--timeout= parameter: %s", optarg);
|
||||
return log_error_errno(r, "Failed to parse -t/--timeout= parameter: %s", opts.arg);
|
||||
break;
|
||||
|
||||
case ARG_INITIALIZED:
|
||||
r = parse_boolean(optarg);
|
||||
OPTION_LONG("initialized", "BOOL",
|
||||
"Wait for devices being initialized by systemd-udevd"):
|
||||
r = parse_boolean(opts.arg);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse --initialized= parameter: %s", optarg);
|
||||
return log_error_errno(r, "Failed to parse --initialized= parameter: %s", opts.arg);
|
||||
arg_wait_until = r ? WAIT_UNTIL_INITIALIZED : WAIT_UNTIL_ADDED;
|
||||
break;
|
||||
|
||||
case ARG_REMOVED:
|
||||
OPTION_LONG("removed", NULL, "Wait for devices being removed"):
|
||||
arg_wait_until = WAIT_UNTIL_REMOVED;
|
||||
break;
|
||||
|
||||
case ARG_SETTLE:
|
||||
OPTION_LONG("settle", NULL, "Also wait for all queued events being processed"):
|
||||
arg_settle = true;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
return print_version();
|
||||
|
||||
case 'h':
|
||||
return help();
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
if (optind >= argc)
|
||||
char **args = option_parser_get_args(&opts);
|
||||
if (strv_isempty(args))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Too few arguments, expected at least one device path or device symlink.");
|
||||
|
||||
arg_devices = strv_copy(argv + optind);
|
||||
arg_devices = strv_copy(args);
|
||||
if (!arg_devices)
|
||||
return log_oom();
|
||||
|
||||
|
||||
+58
-81
@@ -1,87 +1,93 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "argv-util.h"
|
||||
#include "format-table.h"
|
||||
#include "help-util.h"
|
||||
#include "label-util.h"
|
||||
#include "main-func.h"
|
||||
#include "pretty-print.h"
|
||||
#include "options.h"
|
||||
#include "udev-util.h"
|
||||
#include "udevadm.h"
|
||||
#include "udevd.h"
|
||||
#include "verbs.h"
|
||||
|
||||
static int help(void) {
|
||||
static const char *const short_descriptions[][2] = {
|
||||
{ "info", "Query sysfs or the udev database" },
|
||||
{ "trigger", "Request events from the kernel" },
|
||||
{ "settle", "Wait for pending udev events" },
|
||||
{ "control", "Control the udev daemon" },
|
||||
{ "monitor", "Listen to kernel and udev events" },
|
||||
{ "test", "Test an event run" },
|
||||
{ "test-builtin", "Test a built-in command" },
|
||||
{ "verify", "Verify udev rules files" },
|
||||
{ "cat", "Show udev rules files" },
|
||||
{ "wait", "Wait for device or device symlink" },
|
||||
{ "lock", "Lock a block device" },
|
||||
};
|
||||
|
||||
_cleanup_free_ char *link = NULL;
|
||||
_cleanup_(table_unrefp) Table *verbs = NULL, *options = NULL;
|
||||
int r;
|
||||
|
||||
r = terminal_urlify_man("udevadm", "8", &link);
|
||||
r = verbs_get_help_table(&verbs);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
return r;
|
||||
|
||||
printf("%s [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n\n"
|
||||
"Send control commands or test the device manager.\n\n"
|
||||
"Commands:\n",
|
||||
program_invocation_short_name);
|
||||
r = option_parser_get_help_table_ns("udevadm", &options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
FOREACH_ELEMENT(desc, short_descriptions)
|
||||
printf(" %-12s %s\n", (*desc)[0], (*desc)[1]);
|
||||
(void) table_sync_column_widths(0, verbs, options);
|
||||
|
||||
printf("\nSee the %s for details.\n", link);
|
||||
help_cmdline("[OPTIONS…] COMMAND [COMMAND OPTIONS…]");
|
||||
help_abstract("Send control commands or test the device manager.");
|
||||
|
||||
help_section("Commands:");
|
||||
r = table_print_or_warn(verbs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_section("Options:");
|
||||
r = table_print_or_warn(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
help_man_page_reference("udevadm", "8");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
static const struct option options[] = {
|
||||
{ "debug", no_argument, NULL, 'd' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{}
|
||||
};
|
||||
int c;
|
||||
VERB_COMMON_HELP(help);
|
||||
|
||||
VERB_SCOPE(, verb_info_main, "info", "[DEVPATH|FILE]", VERB_ANY, VERB_ANY, 0, "Query sysfs or the udev database");
|
||||
VERB_SCOPE(, verb_trigger_main, "trigger", "DEVPATH", VERB_ANY, VERB_ANY, 0, "Request events from the kernel");
|
||||
VERB_SCOPE(, verb_settle_main, "settle", NULL, VERB_ANY, VERB_ANY, 0, "Wait for pending udev events");
|
||||
VERB_SCOPE(, verb_control_main, "control", "OPTION", VERB_ANY, VERB_ANY, 0, "Control the udev daemon");
|
||||
VERB_SCOPE(, verb_monitor_main, "monitor", NULL, VERB_ANY, VERB_ANY, 0, "Listen to kernel and udev events");
|
||||
VERB_SCOPE(, verb_test_main, "test", "DEVPATH", VERB_ANY, VERB_ANY, 0, "Test an event run");
|
||||
VERB_SCOPE(, verb_builtin_main, "test-builtin", "COMMAND DEVPATH", VERB_ANY, VERB_ANY, 0, "Test a built-in command");
|
||||
VERB_SCOPE(, verb_verify_main, "verify", "[FILE…]", VERB_ANY, VERB_ANY, 0, "Verify udev rules files");
|
||||
VERB_SCOPE(, verb_cat_main, "cat", "[FILE…]", VERB_ANY, VERB_ANY, 0, "Show udev rules files");
|
||||
VERB_SCOPE(, verb_wait_main, "wait", "DEVICE [DEVICE…]", VERB_ANY, VERB_ANY, 0, "Wait for device or device symlink");
|
||||
VERB_SCOPE(, verb_lock_main, "lock", "[OPTIONS…] COMMAND", VERB_ANY, VERB_ANY, 0, "Lock a block device");
|
||||
VERB_SCOPE(, verb_hwdb_main, "hwdb", NULL, VERB_ANY, VERB_ANY, 0, /* help= */ NULL); /* deprecated */
|
||||
|
||||
VERB_NOARG(verb_version_main, "version", /* help= */ NULL);
|
||||
static int verb_version_main(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
return print_version();
|
||||
}
|
||||
|
||||
static int parse_argv(int argc, char *argv[], char ***remaining_args) {
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
assert(remaining_args);
|
||||
|
||||
/* Resetting to 0 forces the invocation of an internal initialization routine of getopt_long()
|
||||
* that checks for GNU extensions in optstring ('-' or '+' at the beginning). */
|
||||
optind = 0;
|
||||
while ((c = getopt_long(argc, argv, "+dhV", options, NULL)) >= 0)
|
||||
OptionParser opts = { argc, argv, OPTION_PARSER_STOP_AT_FIRST_NONOPTION, "udevadm" };
|
||||
|
||||
FOREACH_OPTION(c, &opts, /* on_error= */ return c)
|
||||
switch (c) {
|
||||
|
||||
case 'd':
|
||||
log_set_max_level(LOG_DEBUG);
|
||||
break;
|
||||
OPTION_NAMESPACE("udevadm"): {}
|
||||
|
||||
case 'h':
|
||||
OPTION_COMMON_HELP:
|
||||
return help();
|
||||
|
||||
case 'V':
|
||||
OPTION_COMMON_VERSION_WITH_HIDDEN_V:
|
||||
return print_version();
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
OPTION('d', "debug", NULL, "Enable debug logging"):
|
||||
log_set_max_level(LOG_DEBUG);
|
||||
break;
|
||||
}
|
||||
|
||||
*remaining_args = option_parser_get_args(&opts);
|
||||
return 1; /* work to do */
|
||||
}
|
||||
|
||||
@@ -91,37 +97,8 @@ int print_version(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verb_version_main(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
return print_version();
|
||||
}
|
||||
|
||||
static int verb_help_main(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
return help();
|
||||
}
|
||||
|
||||
static int udevadm_main(int argc, char *argv[]) {
|
||||
static const Verb verbs[] = {
|
||||
{ "cat", VERB_ANY, VERB_ANY, 0, verb_cat_main },
|
||||
{ "info", VERB_ANY, VERB_ANY, 0, verb_info_main },
|
||||
{ "trigger", VERB_ANY, VERB_ANY, 0, verb_trigger_main },
|
||||
{ "settle", VERB_ANY, VERB_ANY, 0, verb_settle_main },
|
||||
{ "control", VERB_ANY, VERB_ANY, 0, verb_control_main },
|
||||
{ "monitor", VERB_ANY, VERB_ANY, 0, verb_monitor_main },
|
||||
{ "hwdb", VERB_ANY, VERB_ANY, 0, verb_hwdb_main },
|
||||
{ "test", VERB_ANY, VERB_ANY, 0, verb_test_main },
|
||||
{ "test-builtin", VERB_ANY, VERB_ANY, 0, verb_builtin_main },
|
||||
{ "wait", VERB_ANY, VERB_ANY, 0, verb_wait_main },
|
||||
{ "lock", VERB_ANY, VERB_ANY, 0, verb_lock_main },
|
||||
{ "verify", VERB_ANY, VERB_ANY, 0, verb_verify_main },
|
||||
{ "version", VERB_ANY, VERB_ANY, 0, verb_version_main },
|
||||
{ "help", VERB_ANY, VERB_ANY, 0, verb_help_main },
|
||||
{}
|
||||
};
|
||||
|
||||
return dispatch_verb(argc, argv, verbs, NULL);
|
||||
}
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
char **args = NULL;
|
||||
int r;
|
||||
|
||||
if (invoked_as(argv, "udevd"))
|
||||
@@ -130,7 +107,7 @@ static int run(int argc, char *argv[]) {
|
||||
(void) udev_parse_config();
|
||||
log_setup();
|
||||
|
||||
r = parse_argv(argc, argv);
|
||||
r = parse_argv(argc, argv, &args);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@@ -138,7 +115,7 @@ static int run(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return udevadm_main(argc, argv);
|
||||
return dispatch_verb_with_args(args, NULL);
|
||||
}
|
||||
|
||||
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);
|
||||
|
||||
Reference in New Issue
Block a user