]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udevadm: allow multiple arguments to "info" 11107/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 10 Dec 2018 13:02:39 +0000 (14:02 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 11 Dec 2018 08:29:21 +0000 (09:29 +0100)
This matches udevadm trigger, which allows multiple arguments since
80877656a55.

man/udevadm.xml
src/udev/udevadm-info.c

index ac3198b1f87f9f74fe3915a2cd2cdb7ae236b379..44be7b3f894b5117dc5f5bdf152e2e1d16ab72c7 100644 (file)
 
     <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>
index 31a6291279be0907cbeef2bdad936080db930370..d141bc74b2a10fc91d255c687b9659cfeaf6504c 100644 (file)
@@ -335,7 +335,7 @@ static int help(void) {
 }
 
 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;
 
@@ -361,25 +361,20 @@ int info_main(int argc, char *argv[], void *userdata) {
         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"))
@@ -430,35 +425,45 @@ int info_main(int argc, char *argv[], void *userdata) {
                         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;
 }