chiark / gitweb /
udev: in addition to DEVMODE, honor DEVUID, DEVGID from the uevent
[elogind.git] / src / libudev / libudev-device.c
index acf8e24d159abc42d0e9ab9db9d54b1f151921f7..f218b0278a20559e6966fecba452591762cee7c1 100644 (file)
@@ -60,6 +60,8 @@ struct udev_device {
         const char *sysnum;
         char *devnode;
         mode_t devnode_mode;
+        uid_t devnode_uid;
+        gid_t devnode_gid;
         char *subsystem;
         char *devtype;
         char *driver;
@@ -323,6 +325,40 @@ static int udev_device_set_devnode_mode(struct udev_device *udev_device, mode_t
         return 0;
 }
 
+uid_t udev_device_get_devnode_uid(struct udev_device *udev_device)
+{
+        if (!udev_device->info_loaded)
+                udev_device_read_uevent_file(udev_device);
+        return udev_device->devnode_uid;
+}
+
+static int udev_device_set_devnode_uid(struct udev_device *udev_device, uid_t uid)
+{
+        char num[32];
+
+        udev_device->devnode_uid = uid;
+        snprintf(num, sizeof(num), "%u", uid);
+        udev_device_add_property(udev_device, "DEVUID", num);
+        return 0;
+}
+
+gid_t udev_device_get_devnode_gid(struct udev_device *udev_device)
+{
+        if (!udev_device->info_loaded)
+                udev_device_read_uevent_file(udev_device);
+        return udev_device->devnode_gid;
+}
+
+static int udev_device_set_devnode_gid(struct udev_device *udev_device, gid_t gid)
+{
+        char num[32];
+
+        udev_device->devnode_gid = gid;
+        snprintf(num, sizeof(num), "%u", gid);
+        udev_device_add_property(udev_device, "DEVGID", num);
+        return 0;
+}
+
 struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value)
 {
         udev_device->envp_uptodate = false;
@@ -430,6 +466,10 @@ void udev_device_add_property_from_string_parse(struct udev_device *udev_device,
                 udev_device_set_ifindex(udev_device, strtoull(&property[8], NULL, 10));
         } else if (startswith(property, "DEVMODE=")) {
                 udev_device_set_devnode_mode(udev_device, strtoul(&property[8], NULL, 8));
+        } else if (startswith(property, "DEVUID=")) {
+                udev_device_set_devnode_uid(udev_device, strtoul(&property[7], NULL, 10));
+        } else if (startswith(property, "DEVGID=")) {
+                udev_device_set_devnode_gid(udev_device, strtoul(&property[7], NULL, 10));
         } else {
                 udev_device_add_property_from_string(udev_device, property);
         }
@@ -1358,16 +1398,17 @@ _public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_devi
                         goto out;
                 }
 
-                /* resolve link to a device and return its syspath */
-                util_strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL);
-                dev = udev_device_new_from_syspath(udev_device->udev, path);
-                if (dev != NULL) {
-                        list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr,
-                                                         udev_device_get_syspath(dev));
-                        val = udev_list_entry_get_value(list_entry);
-                        udev_device_unref(dev);
+                /* resolve custom link to a device and return its syspath */
+                if (!streq(sysattr, "device")) {
+                        util_strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL);
+                        dev = udev_device_new_from_syspath(udev_device->udev, path);
+                        if (dev != NULL) {
+                                list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr,
+                                                                 udev_device_get_syspath(dev));
+                                val = udev_list_entry_get_value(list_entry);
+                                udev_device_unref(dev);
+                        }
                 }
-
                 goto out;
         }