chiark / gitweb /
rules: switch to built-in blkid
[elogind.git] / libudev / libudev-device.c
index 025527bb8ab59f2114e34d812c5d8d48d5755b20..1024b46803b9d447611bb289ca6d7355b36d05fd 100644 (file)
@@ -62,11 +62,11 @@ struct udev_device {
        char **envp;
        char *monitor_buf;
        size_t monitor_buf_len;
-       struct udev_list_node devlinks_list;
-       struct udev_list_node properties_list;
-       struct udev_list_node sysattr_value_list;
-       struct udev_list_node sysattr_list;
-       struct udev_list_node tags_list;
+       struct udev_list devlinks_list;
+       struct udev_list properties_list;
+       struct udev_list sysattr_value_list;
+       struct udev_list sysattr_list;
+       struct udev_list tags_list;
        unsigned long long int seqnum;
        unsigned long long int usec_initialized;
        int timeout;
@@ -92,7 +92,7 @@ struct udev_device {
 };
 
 /**
- * udev_device_get_devnum:
+ * udev_device_get_seqnum:
  * @udev_device: udev device
  *
  * This is only valid if the device was received through a monitor. Devices read from
@@ -229,7 +229,7 @@ UDEV_EXPORT const char *udev_device_get_driver(struct udev_device *udev_device)
                return NULL;
        if (!udev_device->driver_set) {
                udev_device->driver_set = true;
-               if (util_get_sys_driver(udev_device->udev, udev_device->syspath, driver, sizeof(driver)) > 0)
+               if (util_get_sys_core_link_value(udev_device->udev, "driver", udev_device->syspath, driver, sizeof(driver)) > 0)
                        udev_device->driver = strdup(driver);
        }
        return udev_device->driver;
@@ -305,7 +305,7 @@ UDEV_EXPORT const char *udev_device_get_subsystem(struct udev_device *udev_devic
        if (!udev_device->subsystem_set) {
                udev_device->subsystem_set = true;
                /* read "subsystem" link */
-               if (util_get_sys_subsystem(udev_device->udev, udev_device->syspath, subsystem, sizeof(subsystem)) > 0) {
+               if (util_get_sys_core_link_value(udev_device->udev, "subsystem", udev_device->syspath, subsystem, sizeof(subsystem)) > 0) {
                        udev_device_set_subsystem(udev_device, subsystem);
                        return udev_device->subsystem;
                }
@@ -357,7 +357,7 @@ struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device
                        udev_list_entry_delete(list_entry);
                return NULL;
        }
-       return udev_list_entry_add(udev_device->udev, &udev_device->properties_list, key, value, UDEV_LIST_UNIQUE);
+       return udev_list_entry_add(&udev_device->properties_list, key, value);
 }
 
 static struct udev_list_entry *udev_device_add_property_from_string(struct udev_device *udev_device, const char *property)
@@ -437,6 +437,8 @@ void udev_device_add_property_from_string_parse(struct udev_device *udev_device,
                                udev_device_add_tag(udev_device, tag);
                        }
                }
+       } else if (strncmp(property, "USEC_INITIALIZED=", 19) == 0) {
+               udev_device_set_usec_initialized(udev_device, strtoull(&property[19], NULL, 10));
        } else if (strncmp(property, "DRIVER=", 7) == 0) {
                udev_device_set_driver(udev_device, &property[7]);
        } else if (strncmp(property, "ACTION=", 7) == 0) {
@@ -489,7 +491,7 @@ UDEV_EXPORT const char *udev_device_get_property_value(struct udev_device *udev_
                return NULL;
 
        list_entry = udev_device_get_properties_list_entry(udev_device);
-       list_entry =  udev_list_entry_get_by_name(list_entry, key);
+       list_entry = udev_list_entry_get_by_name(list_entry, key);
        return udev_list_entry_get_value(list_entry);
 }
 
@@ -628,11 +630,11 @@ struct udev_device *udev_device_new(struct udev *udev)
                return NULL;
        udev_device->refcount = 1;
        udev_device->udev = udev;
-       udev_list_init(&udev_device->devlinks_list);
-       udev_list_init(&udev_device->properties_list);
-       udev_list_init(&udev_device->sysattr_value_list);
-       udev_list_init(&udev_device->sysattr_list);
-       udev_list_init(&udev_device->tags_list);
+       udev_list_init(udev, &udev_device->devlinks_list, true);
+       udev_list_init(udev, &udev_device->properties_list, true);
+       udev_list_init(udev, &udev_device->sysattr_value_list, true);
+       udev_list_init(udev, &udev_device->sysattr_list, false);
+       udev_list_init(udev, &udev_device->tags_list, true);
        udev_device->timeout = -1;
        udev_device->watch_handle = -1;
        /* copy global properties */
@@ -1082,11 +1084,11 @@ UDEV_EXPORT void udev_device_unref(struct udev_device *udev_device)
        free(udev_device->devnode);
        free(udev_device->subsystem);
        free(udev_device->devtype);
-       udev_list_cleanup_entries(udev_device->udev, &udev_device->devlinks_list);
-       udev_list_cleanup_entries(udev_device->udev, &udev_device->properties_list);
-       udev_list_cleanup_entries(udev_device->udev, &udev_device->sysattr_value_list);
-       udev_list_cleanup_entries(udev_device->udev, &udev_device->sysattr_list);
-       udev_list_cleanup_entries(udev_device->udev, &udev_device->tags_list);
+       udev_list_cleanup(&udev_device->devlinks_list);
+       udev_list_cleanup(&udev_device->properties_list);
+       udev_list_cleanup(&udev_device->sysattr_value_list);
+       udev_list_cleanup(&udev_device->sysattr_list);
+       udev_list_cleanup(&udev_device->tags_list);
        free(udev_device->action);
        free(udev_device->driver);
        free(udev_device->devpath_old);
@@ -1212,7 +1214,7 @@ UDEV_EXPORT struct udev_list_entry *udev_device_get_devlinks_list_entry(struct u
 void udev_device_cleanup_devlinks_list(struct udev_device *udev_device)
 {
        udev_device->devlinks_uptodate = false;
-       udev_list_cleanup_entries(udev_device->udev, &udev_device->devlinks_list);
+       udev_list_cleanup(&udev_device->devlinks_list);
 }
 
 /**
@@ -1322,7 +1324,11 @@ unsigned long long udev_device_get_usec_initialized(struct udev_device *udev_dev
 
 void udev_device_set_usec_initialized(struct udev_device *udev_device, unsigned long long usec_initialized)
 {
+       char num[32];
+
        udev_device->usec_initialized = usec_initialized;
+       snprintf(num, sizeof(num), "%llu", usec_initialized);
+       udev_device_add_property(udev_device, "USEC_INITIALIZED", num);
 }
 
 /**
@@ -1351,43 +1357,48 @@ UDEV_EXPORT const char *udev_device_get_sysattr_value(struct udev_device *udev_d
                return NULL;
 
        /* look for possibly already cached result */
-       udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_device->sysattr_value_list)) {
-               if (strcmp(udev_list_entry_get_name(list_entry), sysattr) == 0) {
-                       dbg(udev_device->udev, "got '%s' (%s) from cache\n",
-                           sysattr, udev_list_entry_get_value(list_entry));
-                       return udev_list_entry_get_value(list_entry);
-               }
+       list_entry = udev_list_get_entry(&udev_device->sysattr_value_list);
+       list_entry = udev_list_entry_get_by_name(list_entry, sysattr);
+       if (list_entry != NULL) {
+               dbg(udev_device->udev, "got '%s' (%s) from cache\n",
+                   sysattr, udev_list_entry_get_value(list_entry));
+               return udev_list_entry_get_value(list_entry);
        }
 
        util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", sysattr, NULL);
        if (lstat(path, &statbuf) != 0) {
                dbg(udev_device->udev, "no attribute '%s', keep negative entry\n", path);
-               udev_list_entry_add(udev_device->udev, &udev_device->sysattr_value_list, sysattr, NULL, 0);
+               udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, NULL);
                goto out;
        }
 
        if (S_ISLNK(statbuf.st_mode)) {
-               char target[UTIL_NAME_SIZE];
-               int len;
-               char *pos;
-
-               /* some core links return the last element of the target path */
-               if (strcmp(sysattr, "driver") != 0 &&
-                   strcmp(sysattr, "subsystem") != 0 &&
-                   strcmp(sysattr, "module") != 0)
-                       goto out;
+               struct udev_device *dev;
 
-               len = readlink(path, target, sizeof(target));
-               if (len <= 0 || len == sizeof(target))
+               /*
+                * Some core links return only the last element of the target path,
+                * these are just values, the paths should not be exposed.
+                */
+               if (strcmp(sysattr, "driver") == 0 ||
+                   strcmp(sysattr, "subsystem") == 0 ||
+                   strcmp(sysattr, "module") == 0) {
+                       if (util_get_sys_core_link_value(udev_device->udev, sysattr,
+                                                        udev_device->syspath, value, sizeof(value)) < 0)
+                               return NULL;
+                       dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, value);
+                       list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value);
+                       val = udev_list_entry_get_value(list_entry);
                        goto out;
-               target[len] = '\0';
+               }
 
-               pos = strrchr(target, '/');
-               if (pos != NULL) {
-                       pos = &pos[1];
-                       dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, pos);
-                       list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_value_list, sysattr, pos, 0);
+               /* 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);
                }
 
                goto out;
@@ -1418,7 +1429,7 @@ UDEV_EXPORT const char *udev_device_get_sysattr_value(struct udev_device *udev_d
        value[size] = '\0';
        util_remove_trailing_chars(value, '\n');
        dbg(udev_device->udev, "'%s' has attribute value '%s'\n", path, value);
-       list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_value_list, sysattr, value, 0);
+       list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value);
        val = udev_list_entry_get_value(list_entry);
 out:
        return val;
@@ -1456,8 +1467,7 @@ static int udev_device_sysattr_list_read(struct udev_device *udev_device)
                if ((statbuf.st_mode & S_IRUSR) == 0)
                        continue;
 
-               udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list,
-                                   dent->d_name, NULL, 0);
+               udev_list_entry_add(&udev_device->sysattr_list, dent->d_name, NULL);
                num++;
        }
 
@@ -1543,7 +1553,7 @@ int udev_device_add_devlink(struct udev_device *udev_device, const char *devlink
        struct udev_list_entry *list_entry;
 
        udev_device->devlinks_uptodate = false;
-       list_entry = udev_list_entry_add(udev_device->udev, &udev_device->devlinks_list, devlink, NULL, UDEV_LIST_UNIQUE);
+       list_entry = udev_list_entry_add(&udev_device->devlinks_list, devlink, NULL);
        if (list_entry == NULL)
                return -ENOMEM;
        if (unique)
@@ -1615,7 +1625,7 @@ 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, UDEV_LIST_UNIQUE) != NULL)
+       if (udev_list_entry_add(&udev_device->tags_list, tag, NULL) != NULL)
                return 0;
        return -ENOMEM;
 }
@@ -1623,7 +1633,7 @@ int udev_device_add_tag(struct udev_device *udev_device, const char *tag)
 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_list_cleanup(&udev_device->tags_list);
 }
 
 /**