<refsect2><title>udevadm info
<arg choice="opt"><replaceable>options</replaceable></arg>
- <arg choice="opt"><replaceable>devpath</replaceable>|<replaceable>file</replaceable>|<replaceable>unit</replaceable></arg>
+ <arg choice="opt" rep="repeat"><replaceable>devpath</replaceable>|<replaceable>file</replaceable>|<replaceable>unit</replaceable></arg>
</title>
<para>Query the udev database for device information.</para>
- <para>A positional argument should be used to specify a device. It may be a device name (in which case
- it must start with <filename>/dev/</filename>), a sys path (in which case it must start with
- <filename>/sys/</filename>), or a systemd device unit name (in which case it must end with
+ <para>Positional arguments should be used to specify one or more devices. Each one may be a device name
+ (in which case it must start with <filename>/dev/</filename>), a sys path (in which case it must start
+ with <filename>/sys/</filename>), or a systemd device unit name (in which case it must end with
<literal>.device</literal>, see
<citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
</para>
}
int info_main(int argc, char *argv[], void *userdata) {
- _cleanup_(sd_device_unrefp) sd_device *device = NULL;
+ _cleanup_strv_free_ char **devices = NULL;
_cleanup_free_ char *name = NULL;
int c, r;
while ((c = getopt_long(argc, argv, "aced:n:p:q:rxP:RVh", options, NULL)) >= 0)
switch (c) {
case 'n':
- if (device) {
- log_error("device already specified");
- return -EINVAL;
- }
+ case 'p': {
+ const char *prefix = c == 'n' ? "/dev/" : "/sys/";
+ char *path;
- r = find_device(optarg, "/dev/", &device);
- if (r < 0)
- return log_error_errno(r, "device node not found: %m");
- break;
- case 'p':
- if (device) {
- log_error("device already specified");
- return -EINVAL;
- }
+ path = path_join(path_startswith(optarg, prefix) ? NULL : prefix, optarg);
+ if (!path)
+ return log_oom();
- r = find_device(optarg, "/sys", &device);
+ r = strv_consume(&devices, path);
if (r < 0)
- return log_error_errno(r, "syspath not found: %m");
+ return log_oom();
break;
+ }
+
case 'q':
action = ACTION_QUERY;
if (streq(optarg, "property") || streq(optarg, "env"))
assert_not_reached("Unknown option");
}
- if (IN_SET(action, ACTION_QUERY, ACTION_ATTRIBUTE_WALK) &&
- !device) {
- /* A device argument is required. It may be an option or a positional arg. */
- if (!argv[optind])
+ if (action == ACTION_DEVICE_ID_FILE) {
+ if (argv[optind])
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "A device name or path is required");
-
- r = find_device(argv[optind], NULL, &device);
- if (r == -EINVAL)
- return log_error_errno(r, "Bad argument \"%s\", expected an absolute path in /dev/ or /sys or a unit name: %m",
- argv[optind]);
- if (r < 0)
- return log_error_errno(r, "Unknown device \"%s\": %m", argv[optind]);
+ "Positional arguments are not allowed with -d/--device-id-of-file.");
+ assert(name);
+ return stat_device(name, arg_export, arg_export_prefix);
}
- switch (action) {
- case ACTION_QUERY:
- assert(device);
- return query_device(query, device);
+ r = strv_extend_strv(&devices, argv + optind, false);
+ if (r < 0)
+ return log_error_errno(r, "Failed to build argument list: %m");
- case ACTION_ATTRIBUTE_WALK:
- assert(device);
- return print_device_chain(device);
+ if (strv_isempty(devices))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "A device name or path is required");
+ if (action == ACTION_ATTRIBUTE_WALK && strv_length(devices) > 1)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "Only one device may be specified with -a/--attribute-walk");
- case ACTION_DEVICE_ID_FILE:
- assert(name);
- return stat_device(name, arg_export, arg_export_prefix);
+ char **p;
+ STRV_FOREACH(p, devices) {
+ _cleanup_(sd_device_unrefp) sd_device *device = NULL;
+
+ r = find_device(*p, NULL, &device);
+ if (r == -EINVAL)
+ return log_error_errno(r, "Bad argument \"%s\", expected an absolute path in /dev/ or /sys or a unit name: %m", *p);
+ if (r < 0)
+ return log_error_errno(r, "Unknown device \"%s\": %m", *p);
+
+ if (action == ACTION_QUERY)
+ r = query_device(query, device);
+ else if (action == ACTION_ATTRIBUTE_WALK)
+ r = print_device_chain(device);
+ else
+ assert_not_reached("Unknown action");
+ if (r < 0)
+ return r;
}
- assert_not_reached("Unknown action");
+ return 0;
}