chiark / gitweb /
udev: in addition to DEVMODE, honor DEVUID, DEVGID from the uevent
authorKay Sievers <kay@vrfy.org>
Mon, 31 Dec 2012 03:48:44 +0000 (04:48 +0100)
committerKay Sievers <kay@vrfy.org>
Mon, 31 Dec 2012 03:48:44 +0000 (04:48 +0100)
src/libudev/libudev-device.c
src/libudev/libudev-private.h
src/udev/udev-event.c
src/udev/udev-rules.c
src/udev/udev.h

index d246d012b232d2268f426714963ba99026fda406..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);
         }
index ff1cc8cefd07cb101a5ccf82060c42d40f3e6f18..5b7f0021e93de4e738314fc8d3bbe508f19ec7ce 100644 (file)
@@ -56,6 +56,8 @@ struct udev_list_entry *udev_get_properties_list_entry(struct udev *udev);
 /* libudev-device.c */
 struct udev_device *udev_device_new(struct udev *udev);
 mode_t udev_device_get_devnode_mode(struct udev_device *udev_device);
+uid_t udev_device_get_devnode_uid(struct udev_device *udev_device);
+gid_t udev_device_get_devnode_gid(struct udev_device *udev_device);
 int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem);
 int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath);
 int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode);
index b75ed33fbf8a6a0f8a663c60c5d4ce2ebe3797b5..5eedf4f0dfdad2530eb5d25462dd654930ceba71 100644 (file)
@@ -842,6 +842,12 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules,
                         if (event->dev_db != NULL)
                                 udev_node_update_old_links(dev, event->dev_db);
 
+                        if (!event->owner_set)
+                                event->uid = udev_device_get_devnode_uid(dev);
+
+                        if (!event->group_set)
+                                event->gid = udev_device_get_devnode_gid(dev);
+
                         if (!event->mode_set) {
                                 if (udev_device_get_devnode_mode(dev) > 0) {
                                         /* kernel supplied value */
index e6f0f5da7eeec3871a5de5e56484297f084921fa..9743243a3777f9f98f5df6dcae348c778936c1f2 100644 (file)
@@ -2224,6 +2224,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                         if (cur->key.op == OP_ASSIGN_FINAL)
                                 event->owner_final = true;
                         udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner));
+                        event->owner_set = true;
                         event->uid = util_lookup_user(event->udev, owner);
                         log_debug("OWNER %u %s:%u\n",
                                   event->uid,
@@ -2239,6 +2240,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                         if (cur->key.op == OP_ASSIGN_FINAL)
                                 event->group_final = true;
                         udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group));
+                        event->group_set = true;
                         event->gid = util_lookup_group(event->udev, group);
                         log_debug("GROUP %u %s:%u\n",
                                   event->gid,
@@ -2274,6 +2276,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                                 break;
                         if (cur->key.op == OP_ASSIGN_FINAL)
                                 event->owner_final = true;
+                        event->owner_set = true;
                         event->uid = cur->key.uid;
                         log_debug("OWNER %u %s:%u\n",
                                   event->uid,
@@ -2285,6 +2288,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
                                 break;
                         if (cur->key.op == OP_ASSIGN_FINAL)
                                 event->group_final = true;
+                        event->group_set = true;
                         event->gid = cur->key.gid;
                         log_debug("GROUP %u %s:%u\n",
                                   event->gid,
index 32779ba48614c238de66469f39b6ffea21f0b13f..72a7623e34c1856fcda11923bcd8aba845cd987f 100644 (file)
@@ -49,7 +49,9 @@ struct udev_event {
         bool sigterm;
         bool inotify_watch;
         bool inotify_watch_final;
+        bool group_set;
         bool group_final;
+        bool owner_set;
         bool owner_final;
         bool mode_set;
         bool mode_final;