+const char *udev_device_get_id_filename(struct udev_device *udev_device)
+{
+ if (udev_device->id_filename == NULL) {
+ if (udev_device_get_subsystem(udev_device) == NULL)
+ return NULL;
+
+ if (major(udev_device_get_devnum(udev_device)) > 0) {
+ /* use dev_t -- b259:131072, c254:0 */
+ if (asprintf(&udev_device->id_filename, "%c%u:%u",
+ strcmp(udev_device_get_subsystem(udev_device), "block") == 0 ? 'b' : 'c',
+ major(udev_device_get_devnum(udev_device)),
+ minor(udev_device_get_devnum(udev_device))) < 0)
+ udev_device->id_filename = NULL;
+ } else if (strcmp(udev_device_get_subsystem(udev_device), "net") == 0) {
+ /* use netdev ifindex -- n3 */
+ if (asprintf(&udev_device->id_filename, "n%u", udev_device_get_ifindex(udev_device)) < 0)
+ udev_device->id_filename = NULL;
+ } else {
+ /*
+ * use $subsys:$syname -- pci:0000:00:1f.2
+ * sysname() has '!' translated, get it from devpath
+ */
+ const char *sysname;
+ sysname = strrchr(udev_device->devpath, '/');
+ if (sysname == NULL)
+ return NULL;
+ sysname = &sysname[1];
+ if (asprintf(&udev_device->id_filename, "+%s:%s", udev_device_get_subsystem(udev_device), sysname) < 0)
+ udev_device->id_filename = NULL;
+ }
+ }
+ return udev_device->id_filename;
+}
+
+int udev_device_add_tag(struct udev_device *udev_device, const char *tag)
+{
+ if (strchr(tag, ':') != NULL || strchr(tag, ' ') != NULL)
+ return -EINVAL;
+ udev_device->tags_uptodate = false;
+ if (udev_list_entry_add(udev_device->udev, &udev_device->tags_list, tag, NULL, 1, 0) != NULL)
+ return 0;
+ return -ENOMEM;
+}
+
+void udev_device_cleanup_tags_list(struct udev_device *udev_device)
+{
+ udev_device->tags_uptodate = false;
+ udev_list_cleanup_entries(udev_device->udev, &udev_device->tags_list);
+}
+
+/**
+ * udev_device_get_tags_list_entry:
+ * @udev_device: udev device
+ *
+ * Retrieve the list of tags attached to the udev device. The next
+ * list entry can be retrieved with udev_list_entry_next(),
+ * which returns #NULL if no more entries exist. The tag string
+ * can be retrieved from the list entry by udev_list_get_name().
+ *
+ * Returns: the first entry of the tag list
+ **/
+struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device)
+{
+ if (udev_device == NULL)
+ return NULL;
+ return udev_list_get_entry(&udev_device->tags_list);
+}
+
+int udev_device_has_tag(struct udev_device *udev_device, const char *tag)
+{
+ struct udev_list_entry *list_entry;
+
+ if (!udev_device->info_loaded)
+ udev_device_read_db(udev_device);
+ list_entry = udev_device_get_tags_list_entry(udev_device);
+ list_entry = udev_list_entry_get_by_name(list_entry, tag);
+ if (list_entry != NULL)
+ return 1;
+ return 0;
+}
+